23. Dynamic Datatypes and Memory Management
Transcript of 23. Dynamic Datatypes and Memory Management
![Page 1: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/1.jpg)
23. Dynamic Datatypes and MemoryManagement
688
![Page 2: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/2.jpg)
Problem
Last week: dynamic data typeHave allocated dynamic memory, but not released it again. In particular:no functions to remove elements from llvec.Today: correct memory management!
689
![Page 3: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/3.jpg)
Goal: class stack with memory management
class stack{public:
// post: Push an element onto the stackvoid push(int value);// pre: non-empty stack// post: Delete top most element from the stackvoid pop();// pre: non-empty stack// post: return value of top most elementint top() const;// post: return if stack is emptybool empty() const;// post: print out the stackvoid print(std::ostream& out) const;
... 690
![Page 4: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/4.jpg)
Recall the Linked List
1 5 6
element (type llnode)
value (type int) next (type llnode*)
struct llnode {int value;llnode* next;// constructorllnode (int v, llnode* n) : value (v), next (n) {}
};
691
![Page 5: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/5.jpg)
Stack = Pointer to the Top Element
1 5 6
element (type llnode)
value (type int) next (type llnode*)
class stack {public:
void push (int value);...
private:llnode* topn;
};
692
![Page 6: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/6.jpg)
Recall the new Expression
new T(...)
underlying type
new-Operator constructor arguments
E�ect: memory for a new object of type T is allocated . . .. . . and initialized by means of the matching constructorValue: address of the new T object, Type: Pointer T*!
693
![Page 7: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/7.jpg)
The new Expression push(4)
E�ect: new object of type T is allocated in memory . . .. . . and intialized by means of the matching constructorValue: address of the new object
void stack::push(int value) {topn = new llnode(value, topn);
}
topn
1 5 6
694
![Page 8: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/8.jpg)
The new Expression push(4)
E�ect: new object of type T is allocated in memory . . .
. . . and intialized by means of the matching constructorValue: address of the new object
void stack::push(int value) {topn = new llnode(value, topn);
}
topn
1 5 6
694
![Page 9: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/9.jpg)
The new Expression push(4)
E�ect: new object of type T is allocated in memory . . .. . . and intialized by means of the matching constructor
Value: address of the new object
void stack::push(int value) {topn = new llnode(value, topn);
}
topn
1 5 64
694
![Page 10: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/10.jpg)
The new Expression push(4)
E�ect: new object of type T is allocated in memory . . .. . . and intialized by means of the matching constructorValue: address of the new object
void stack::push(int value) {topn = new llnode(value, topn);
}
topn
1 5 64
694
![Page 11: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/11.jpg)
The delete Expression
Objects generated with new have dynamic storage duration: they “live”until they are explicitly deleted
delete exprdelete-Operator pointer of type T*, pointing to an object
that had been created with new.
type void
E�ect: object is deconstructed (explanation below)... and memory is released.
695
![Page 12: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/12.jpg)
The delete Expression
Objects generated with new have dynamic storage duration: they “live”until they are explicitly deleted
delete exprdelete-Operator pointer of type T*, pointing to an object
that had been created with new.
type void
E�ect: object is deconstructed (explanation below)... and memory is released.
695
![Page 13: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/13.jpg)
The delete Expression
Objects generated with new have dynamic storage duration: they “live”until they are explicitly deleted
delete exprdelete-Operator pointer of type T*, pointing to an object
that had been created with new.
type void
E�ect: object is deconstructed (explanation below)... and memory is released.
695
![Page 14: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/14.jpg)
delete for Arrays
delete[] expr
delete-Operatorpointer of type T*, that pointsto an array that previouslyhad been allocated using new
type void
E�ect: array is deleted and memory is released
696
![Page 15: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/15.jpg)
Who is born must die. . .
Guideline “Dynamic Memory”
For each new there is a matching delete!
697
![Page 16: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/16.jpg)
Who is born must die. . .
Guideline “Dynamic Memory”
For each new there is a matching delete!
Non-compliance leads to memory leaks
old objects that occupy memory. . .. . . until it is full (heap overflow)
697
![Page 17: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/17.jpg)
Who is born must die. . .
Guideline “Dynamic Memory”
For each new there is a matching delete!
Non-compliance leads to memory leaksold objects that occupy memory. . .
. . . until it is full (heap overflow)
697
![Page 18: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/18.jpg)
Who is born must die. . .
Guideline “Dynamic Memory”
For each new there is a matching delete!
Non-compliance leads to memory leaksold objects that occupy memory. . .. . . until it is full (heap overflow)
697
![Page 19: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/19.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
Pointer to released objects: dangling pointers
Releasing an object more than once using delete is a similar severeerror
698
![Page 20: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/20.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
memory for t is allocated
Pointer to released objects: dangling pointers
Releasing an object more than once using delete is a similar severeerror
698
![Page 21: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/21.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
memory for t is allocatedother pointers may point to the same object
Pointer to released objects: dangling pointers
Releasing an object more than once using delete is a similar severeerror
698
![Page 22: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/22.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
memory for t is allocatedother pointers may point to the same object
... and used for releaseing the object
Pointer to released objects: dangling pointers
Releasing an object more than once using delete is a similar severeerror
698
![Page 23: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/23.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
memory for t is allocatedother pointers may point to the same object
... and used for releaseing the objecterror: memory released!
Dereferencing of „dangling pointers”Pointer to released objects: dangling pointers
Releasing an object more than once using delete is a similar severeerror
698
![Page 24: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/24.jpg)
Careful with new and delete!
rational* t = new rational;rational* s = t;delete s;int nominator = (*t).denominator();
memory for t is allocatedother pointers may point to the same object
... and used for releaseing the objecterror: memory released!
Dereferencing of „dangling pointers”Pointer to released objects: dangling pointersReleasing an object more than once using delete is a similar severeerror
698
![Page 25: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/25.jpg)
Stack Continued: pop()
void stack::pop(){assert (!empty());llnode* p = topn;topn = topn->next;delete p;
}
topn
1 5 6
699
![Page 26: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/26.jpg)
Stack Continued: pop()
void stack::pop(){assert (!empty());llnode* p = topn;topn = topn->next;delete p;
}
topnp
1 5 6
699
![Page 27: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/27.jpg)
Stack Continued: pop()
void stack::pop(){assert (!empty());llnode* p = topn;topn = topn->next;delete p;
}
topnp
1 5 6
699
![Page 28: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/28.jpg)
Stack Continued: pop()
void stack::pop(){assert (!empty());llnode* p = topn;topn = topn->next;delete p;
}
topnp
1 5 6
reminder: shortcut for (*topn).next
699
![Page 29: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/29.jpg)
Stack Continued: pop()
void stack::pop(){assert (!empty());llnode* p = topn;topn = topn->next;delete p;
}
topnp
1 5 6
699
![Page 30: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/30.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " ";}
topn
1 5 6
700
![Page 31: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/31.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " ";}
topn p
1 5 6
700
![Page 32: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/32.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1}
topn p
1 5 6
700
![Page 33: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/33.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1}
topn p
1 5 6
700
![Page 34: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/34.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1 5}
topn p
1 5 6
700
![Page 35: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/35.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1 5}
topn p
1 5 6
700
![Page 36: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/36.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1 5 6}
topn p
1 5 6
700
![Page 37: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/37.jpg)
Print the Stack print()
void stack::print (std::ostream& out) const {for(const llnode* p = topn; p != nullptr; p = p->next)
out << p->value << " "; // 1 5 6}
topn p
1 5 6
700
![Page 38: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/38.jpg)
Output Stack: operator«
class stack {public:
void push (int value);void pop();void print (std::ostream& o) const;...
private:llnode* topn;
};
// POST: s is written to ostd::ostream& operator<< (std::ostream& o, const stack& s){
s.print (o);return o;
} 701
![Page 39: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/39.jpg)
empty(), top()
bool stack::empty() const {return top == nullptr;
}
int stack::top() const {assert(!empty());return topn->value;
}
702
![Page 40: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/40.jpg)
Empty Stack
class stack{public:
stack() : topn (nullptr) {} // default constructor
void push(int value);void pop();void print(std::ostream& out) const;int top() const;bool empty() const;
private:llnode* topn;
}
703
![Page 41: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/41.jpg)
Zombie Elements
{stack s1; // local variables1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
}// s1 has died (become invalid)...
. . . but the three elements of the stack s1 continue to live (memory leak)!They should be released together with s1.
704
![Page 42: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/42.jpg)
Zombie Elements
{stack s1; // local variables1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
}// s1 has died (become invalid)...
. . . but the three elements of the stack s1 continue to live (memory leak)!
They should be released together with s1.
704
![Page 43: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/43.jpg)
Zombie Elements
{stack s1; // local variables1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
}// s1 has died (become invalid)...
. . . but the three elements of the stack s1 continue to live (memory leak)!They should be released together with s1.
704
![Page 44: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/44.jpg)
The Destructor
The Destructor of class T is the unique member function with declaration~T ( );
is automatically called when the memory duration of a class object ends– i.e. when delete is called on an object of type T* or when the enclosingscope of an object of type T ends.If no destructor is declared, it is automatically generated and calls thedestructors for the member variables (pointers topn, no e�ect – reasonfor zombie elements
705
![Page 45: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/45.jpg)
Using a Destructor, it Works
// POST: the dynamic memory of *this is deletedstack::~stack(){
while (topn != nullptr){llnode* t = topn;topn = t->next;delete t;
}}
automatically deletes all stack elements when the stack is beingreleasedNow our stack class seems to follow the guideline “dynamic memory” (?)
706
![Page 46: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/46.jpg)
Using a Destructor, it Works
// POST: the dynamic memory of *this is deletedstack::~stack(){
while (topn != nullptr){llnode* t = topn;topn = t->next;delete t;
}}
automatically deletes all stack elements when the stack is beingreleased
Now our stack class seems to follow the guideline “dynamic memory” (?)
706
![Page 47: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/47.jpg)
Using a Destructor, it Works
// POST: the dynamic memory of *this is deletedstack::~stack(){
while (topn != nullptr){llnode* t = topn;topn = t->next;delete t;
}}
automatically deletes all stack elements when the stack is beingreleasedNow our stack class seems to follow the guideline “dynamic memory” (?)
706
![Page 48: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/48.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n";
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 49: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/49.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n";
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 50: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/50.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n";
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 51: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/51.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n";
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 52: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/52.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 53: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/53.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 54: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/54.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 55: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/55.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
707
![Page 56: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/56.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();
707
![Page 57: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/57.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();
707
![Page 58: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/58.jpg)
Stack Done?
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop (); // Oops, crash!
707
![Page 59: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/59.jpg)
Stack Done? Obviously not. . .
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop (); // Oops, crash!
707
![Page 60: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/60.jpg)
What has gone wrong?
s1
2 3 1
s2
...stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();708
![Page 61: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/61.jpg)
What has gone wrong?
s1
2 3 1
s2
...stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();
member-wise initialization: copies the topnpointer only.
708
![Page 62: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/62.jpg)
What has gone wrong?
s1
2 3 1
s2
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();708
![Page 63: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/63.jpg)
What has gone wrong?
s1
2 3 1
s2
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();708
![Page 64: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/64.jpg)
What has gone wrong?
s1
2 3 1
s2
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();708
![Page 65: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/65.jpg)
What has gone wrong?
s1
2 3 1
s2Pointer to “zombie”!
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();708
![Page 66: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/66.jpg)
What has gone wrong?
s1
2 3 1
s2Pointer to “zombie”!
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop (); // Oops, crash!708
![Page 67: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/67.jpg)
The actual problem
Already this goes wrong:{
stack s1;s1.push(1);stack s2 = s1;
}
When leaving the scope, both stacks are deconstructed. But both stacks tryto delete the same data, because both stacks have access to the samepointer.
709
![Page 68: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/68.jpg)
Possible solutions
Smart-Pointers (we will not go into details here):Count the number of pointers referring to the same objects and deleteonly when that number goes down to 0 std::shared_pointerMake sure that not more than one pointer can point to an object:std::unique_pointer.
or:We make a real copy of all data – as discussed below.
710
![Page 69: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/69.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();711
![Page 70: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/70.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n";
s1.pop ();std::cout << s1 << "\n";
s2.pop ();711
![Page 71: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/71.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();711
![Page 72: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/72.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n";
s2.pop ();711
![Page 73: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/73.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();711
![Page 74: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/74.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop ();711
![Page 75: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/75.jpg)
We make a real copy
s1 2 3 1
s2 2 3 1
...stack s2 = s1;std::cout << s2 << "\n"; // 2 3 1
s1.pop ();std::cout << s1 << "\n"; // 3 1
s2.pop (); // ok711
![Page 76: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/76.jpg)
The Copy Constructor
The copy constructor of a class T is the unique constructor withdeclaration
T ( const T& x );is automatically called when values of type T are initialized with valuesof type T
T x = t; (t of type T)T x (t);
If there is no copy-constructor declared then it is generatedautomatically (and initializes member-wise – reason for the problemabove
712
![Page 77: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/77.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn
2 3 1
713
![Page 78: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/78.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2
3 1
713
![Page 79: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/79.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2
3 1
713
![Page 80: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/80.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2 3
1
713
![Page 81: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/81.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2 3
1
713
![Page 82: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/82.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2 3 1
713
![Page 83: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/83.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2 3 1
713
![Page 84: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/84.jpg)
It works with a Copy Constructor
// POST: *this is initialized with a copy of sstack::stack (const stack& s) : topn (nullptr) {
if (s.topn == nullptr) return;topn = new llnode(s.topn->value, nullptr);llnode* prev = topn;for(llnode* n = s.topn->next; n != nullptr; n = n->next){
llnode* copy = new llnode(n->value, nullptr);prev->next = copy;prev = copy;
}}
s.topn 2 3 1
prev
this->topn 2 3 1
713
![Page 85: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/85.jpg)
Initialization 6= Assignment!
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2 = s1; // Initialisierung
s1.pop ();std::cout << s1 << "\n"; // 3 1s2.pop (); // ok: Copy Constructor!
715
![Page 86: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/86.jpg)
Initialization 6= Assignment!
stack s1;s1.push (1);s1.push (3);s1.push (2);std::cout << s1 << "\n"; // 2 3 1
stack s2;s2 = s1; // Zuweisung
s1.pop ();std::cout << s1 << "\n"; // 3 1s2.pop (); // Oops, Crash!
715
![Page 87: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/87.jpg)
The Assignment Operator
Overloading operator= as a member functionLike the copy-constructor without initializer, but additionally
Releasing memory for the “old” valueCheck for self-assignment (s1=s1) that should not have an e�ect
If there is no assignment operator declared it is automatically generated(and assigns member-wise – reason for the problem above
716
![Page 88: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/88.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s)
{if (topn != s.topn){ // no self-assignment
stack copy = s; // Copy Constructionstd::swap(topn, copy.topn); // now copy has the garbage!
} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 89: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/89.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s){
if (topn != s.topn){ // no self-assignment
stack copy = s; // Copy Constructionstd::swap(topn, copy.topn); // now copy has the garbage!
} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 90: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/90.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s){
if (topn != s.topn){ // no self-assignmentstack copy = s; // Copy Construction
std::swap(topn, copy.topn); // now copy has the garbage!} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 91: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/91.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s){
if (topn != s.topn){ // no self-assignmentstack copy = s; // Copy Constructionstd::swap(topn, copy.topn); // now copy has the garbage!
} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 92: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/92.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s){
if (topn != s.topn){ // no self-assignmentstack copy = s; // Copy Constructionstd::swap(topn, copy.topn); // now copy has the garbage!
} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 93: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/93.jpg)
It works with an Assignment Operator!
// POST: *this (left operand) becomes a// copy of s (right operand)stack& stack::operator= (const stack& s){
if (topn != s.topn){ // no self-assignmentstack copy = s; // Copy Constructionstd::swap(topn, copy.topn); // now copy has the garbage!
} // copy is cleaned up -> deconstructionreturn *this; // return as L-Value (convention)
}
Cooool trick!
717
![Page 94: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/94.jpg)
Done
class stack{public:
stack(); // constructor~stack(); // destructorstack(const stack& s); // copy constructorstack& operator=(const stack& s); // assignment operator
void push(int value);void pop();int top() const;bool empty() const;void print(std::ostream& out) const;
private:llnode* topn;
} 718
![Page 95: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/95.jpg)
Dynamic Datatype
Type that manages dynamic memory (e.g. our class for a stack)Minimal Functionality:
ConstructorsDestructorCopy ConstructorAssignment Operator
719
![Page 96: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/96.jpg)
Dynamic Datatype
Type that manages dynamic memory (e.g. our class for a stack)Minimal Functionality:
ConstructorsDestructorCopy ConstructorAssignment Operator
Rule of Three: if a class defines at leastone of them, it must define all three
719
![Page 97: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/97.jpg)
Trees
Trees areGeneralized lists: nodes can have more than one successorSpecial graphs: graphs consist of nodes and edges. A tree is a fullyconnected, directed, acyclic graph.
720
![Page 98: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/98.jpg)
TreesUse
Decision trees: hierarchic representation ofdecision rulesCode tress: representation of a code, e.g. morsealphabet, hu�man codeSearch trees: allow e�cient searching for anelement by valuesyntax trees: parsing and traversing ofexpressions, e.g. in a compiler
Trees are treated in more detail in other courses (Datastructures and Algorithms (CSE),Algorithms and Complexity (Math Bachelor))
721
![Page 99: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/99.jpg)
(Expression) Trees
-(3-(4-5))*(3+4*5)/6
/
∗
−
−
3 −
4 5
+
3 ∗
4 5
6
leaf
fork
fork
bend
root
parent node (w.r.t. 3∗, ∗)
child node (w.r.t. +)
child node (w.r.t. ∗)
722
![Page 100: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/100.jpg)
(Expression) Trees
-(3-(4-5))*(3+4*5)/6
/
∗
−
−
3 −
4 5
+
3 ∗
4 5
6
leaf
fork
fork
bend
root
parent node (w.r.t. 3∗, ∗)
child node (w.r.t. +)
child node (w.r.t. ∗)
722
![Page 101: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/101.jpg)
(Expression) Trees
-(3-(4-5))*(3+4*5)/6
/
∗
−
−
3 −
4 5
+
3 ∗
4 5
6
leaf
fork
fork
bend
root
parent node (w.r.t. 3∗, ∗)
child node (w.r.t. +)
child node (w.r.t. ∗)
722
![Page 102: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/102.jpg)
(Expression) Trees
-(3-(4-5))*(3+4*5)/6
/
∗
−
−
3 −
4 5
+
3 ∗
4 5
6
leaf
fork
fork
bend
root
parent node (w.r.t. 3∗, ∗)
child node (w.r.t. +)
child node (w.r.t. ∗)
722
![Page 103: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/103.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/
* = 6
tnode
operatorValue left operand
right operand
?: unused
723
![Page 104: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/104.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/
* = 6
tnode
operatorValue left operand
right operand
?: unused
723
![Page 105: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/105.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/
* = 6
tnode
operatorValue left operand
right operand
?: unused
723
![Page 106: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/106.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/
* = 6
tnode
operatorValue left operand
right operand
?: unused
723
![Page 107: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/107.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/
* = 6
tnode
operatorValue left operand
right operand
?: unused
723
![Page 108: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/108.jpg)
Nodes: Forks, Bends or Leaves
/∗ 6
nodenode
/ ?
* ? = 6 ? ?
tnode
operatorValue left operand
right operand
?: unused
723
![Page 109: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/109.jpg)
Nodes (struct tnode)
op val left righttnode
struct tnode {char op; // leaf node: op is ’=’
// internal node: op is ’+’, ’-’, ’*’ or ’/’double val;tnode* left;tnode* right;
tnode(char o, double v, tnode* l, tnode* r): op(o), val(v), left(l), right(r) {}
};
724
![Page 110: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/110.jpg)
Nodes (struct tnode)
op val left righttnode
struct tnode {char op; // leaf node: op is ’=’
// internal node: op is ’+’, ’-’, ’*’ or ’/’double val;tnode* left; // == nullptr for unary minustnode* right;
tnode(char o, double v, tnode* l, tnode* r): op(o), val(v), left(l), right(r) {}
};
724
![Page 111: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/111.jpg)
Nodes (struct tnode)
op val left righttnode
struct tnode {char op; // leaf node: op is ’=’
// internal node: op is ’+’, ’-’, ’*’ or ’/’double val;tnode* left; // == nullptr for unary minustnode* right;
tnode(char o, double v, tnode* l, tnode* r): op(o), val(v), left(l), right(r) {}
};
724
![Page 112: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/112.jpg)
Size = Count Nodes in Subtrees
∗
−
−
3 4
+
3 ∗
4 5
Size of a leave: 1Size of other nodes: 1 + sum of child nodes’ sizeE.g. size of the "+"-node is 5
725
![Page 113: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/113.jpg)
Size = Count Nodes in Subtrees
∗
−
−
3 4
+
3 ∗
4 5
Size of a leave: 1Size of other nodes: 1 + sum of child nodes’ size
E.g. size of the "+"-node is 5
725
![Page 114: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/114.jpg)
Size = Count Nodes in Subtrees
∗
−
−
3 4
+
3 ∗
4 5
Size of a leave: 1Size of other nodes: 1 + sum of child nodes’ sizeE.g. size of the "+"-node is 5
725
![Page 115: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/115.jpg)
Count Nodes in Subtrees
// POST: returns the size (number of nodes) of// the subtree with root nint size (const tnode* n) {
if (n){ // shortcut for n != nullptrreturn size(n->left) + size(n->right) + 1;
}return 0;
}
op val left right
726
![Page 116: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/116.jpg)
Evaluate Subtrees
// POST: evaluates the subtree with root ndouble eval(const tnode* n){
assert(n);if (n->op == ’=’) return n->val;double l = 0;if (n->left) l = eval(n->left);double r = eval(n->right);switch(n->op){
case ’+’: return l+r;case ’-’: return l-r;case ’*’: return l*r;case ’/’: return l/r;default: return 0;
}}
op unary, or left branch
leaf. . .. . . or fork:
right branch
op val left right
727
![Page 117: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/117.jpg)
Cloning Subtrees
// POST: a copy of the subtree with root n is made// and a pointer to its root node is returnedtnode* copy (const tnode* n) {
if (n == nullptr)return nullptr;
return new tnode (n->op, n->val, copy(n->left), copy(n->right));}
op val left right
728
![Page 118: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/118.jpg)
Felling Subtrees
// POST: all nodes in the subtree with root n are deletedvoid clear(tnode* n) {
if(n){clear(n->left);clear(n->right);delete n;
}}
∗
−
−
3 −
4 5
+
3 ∗
4 5
729
![Page 119: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/119.jpg)
Felling Subtrees
// POST: all nodes in the subtree with root n are deletedvoid clear(tnode* n) {
if(n){clear(n->left);clear(n->right);delete n;
}}
∗
−
−
3 −
4 5
+
3 ∗
4 5
729
![Page 120: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/120.jpg)
Felling Subtrees
// POST: all nodes in the subtree with root n are deletedvoid clear(tnode* n) {
if(n){clear(n->left);clear(n->right);delete n;
}}
∗
−
−
3 −
4 5
+
3 ∗
4 5
729
![Page 121: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/121.jpg)
Felling Subtrees
// POST: all nodes in the subtree with root n are deletedvoid clear(tnode* n) {
if(n){clear(n->left);clear(n->right);delete n;
}}
∗
−
−
3 −
4 5
+
3 ∗
4 5
729
![Page 122: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/122.jpg)
Using Expression Subtrees
// Construct a tree for 1 - (-(3 + 7))tnode* n1 = new tnode(’=’, 3, nullptr, nullptr);tnode* n2 = new tnode(’=’, 7, nullptr, nullptr);tnode* n3 = new tnode(’+’, 0, n1, n2);tnode* n4 = new tnode(’-’, 0, nullptr, n3);tnode* n5 = new tnode(’=’, 1, nullptr, nullptr);tnode* root = new tnode(’-’, 0, n5, n4);
// Evaluate the overall treestd::cout << "1 - (-(3 + 7)) = " << eval(root) << ’\n’;
// Evaluate a subtreestd::cout << "3 + 7 = " << eval(n3) << ’\n’;
clear(root); // free memory 730
![Page 123: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/123.jpg)
Planting Trees
class texpression {public:
texpression (double d): root (new tnode (’=’, d, 0, 0)) {}
...private:
tnode* root;};
creates a tree withone leaf
731
![Page 124: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/124.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
*this
root
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 125: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/125.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
*this
root
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 126: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/126.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
*this
root
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 127: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/127.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
*this
root
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 128: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/128.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 129: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/129.jpg)
Letting Trees Grow
texpression& texpression::operator-= (const texpression& e){
assert (e.root);root = new tnode (’-’, 0, root, copy(e.root));return *this;
}
e
e.root
−
e’
copy(e.root)
root
*this
732
![Page 130: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/130.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 131: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/131.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 132: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/132.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 133: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/133.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 134: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/134.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 135: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/135.jpg)
Raising Trees
texpression operator- (const texpression& l,const texpression& r){
texpression result = l;return result -= r;
}
texpression a = 3;texpression b = 4;texpression c = 5;texpression d = a-b-c;
−
−
3 4
5
733
![Page 136: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/136.jpg)
Rule of three: Clone, reproduce and cut trees
texpression::~texpression(){clear(root);
}
texpresssion::texpression (const texpression& e): root(copy(e.root)) { }
texpression& texpression::operator=(const texpression& e){if (root != e.root){
texpression cp = e;std::swap(cp.root, root);
}return *this;
}734
![Page 137: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/137.jpg)
Concluded
class texpression{public:
texpression (double d); // constructor~texpression(); // destructortexpression (const texpression& e); // copy constructortexpression& operator=(const texpression& e); // assignment optexpression operator-();texpression& operator-=(const texpression& e);texpression& operator+=(const texpression& e);texpression& operator*=(const texpression& e);texpression& operator/=(const texpression& e);double evaluate();
private:tnode* root;
}; 735
![Page 138: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/138.jpg)
From values to trees!
// term = factor { "*" factor | "/" factor }double term (std::istream& is){
double value = factor (is);while (true) {
if (consume (is, ’*’))value *= factor (is);
else if (consume (is, ’/’))value /= factor (is);
elsereturn value;
}}
calculator.cpp(expression value)
736
![Page 139: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/139.jpg)
From values to trees!
using number_type = double;
// term = factor { "*" factor | "/" factor }number_type term (std::istream& is){
number_type value = factor (is);while (true) {
if (consume (is, ’*’))value *= factor (is);
else if (consume (is, ’/’))value /= factor (is);
elsereturn value;
}}
double_calculator.cpp(expression value)
736
![Page 140: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/140.jpg)
From values to trees!
using number_type = texpression ;
// term = factor { "*" factor | "/" factor }number_type term (std::istream& is){
number_type value = factor (is);while (true) {
if (consume (is, ’*’))value *= factor (is);
else if (consume (is, ’/’))value /= factor (is);
elsereturn value;
}}
double_calculator.cpp(expression value)→texpression_calculator.cpp(expression tree)
736
![Page 141: 23. Dynamic Datatypes and Memory Management](https://reader036.fdocuments.in/reader036/viewer/2022081419/62a131b4ff2e7451ae512b1a/html5/thumbnails/141.jpg)
Concluding Remark
In this lecture, we have intentionally refrained from implementingmember functions in the node classes of the list or tree.7
When there is inheritace and polymorphism used, the implementation ofthe functionality such as evaluate, print, clear (etc:.) is betterimplemented in member functions.In any case it is not a good idea to implement the memory managementof the composite data strcuture list or tree within the nodes.
7Parts of the implementations are even simpler (because the case n==nullptr can becaught more easily
737