1 Data Structures - CSCI 102 CS102 C++ Composition & Inheritance Prof Tejada.
1 Data Structures - CSCI 102 CS102 C++ Pointers & Dynamic Objects Prof Tejada.
-
Upload
simon-jones -
Category
Documents
-
view
219 -
download
2
Transcript of 1 Data Structures - CSCI 102 CS102 C++ Pointers & Dynamic Objects Prof Tejada.
1
Data Structures - CSCI 102
CS102C++ Pointers &
Dynamic Objects
Prof Tejada
3
Data Structures - CSCI 102
Stack VariablesWhen you create variables normally, they live on thestack and their lifetime is tied to their scope (the { })
int foo() {int x = 5;return x + 1;
}
The variable x is a stack variableMemory for x is created on the stack when foo() is calledMemory for x is "freed" from the stack when foo() returns
Not really "freed", the stack frame is popped
C++ manages memory for stack variables for you.They are automatically created and destroyed.
Stack allocation is mostly handled by the compilerThe compiler generate machine code to push and
pop the program stack
4
Data Structures - CSCI 102
Stack VariablesSometimes stack variables can be really inconvenient
int* bar() {int x;cin >> x;
// Let’s say x got 5return &x;
}
int main() {int *ptr = bar();cout << "*ptr = " << *ptr << endl;
}
This is a really bad idea because x lives on the stack andit will be destroyed when bar() returns
We’ll be returning a pointer to unusable memory
Data Structures - CSCI 102
Stack VariablesSometimes stack variables can be really inconvenient
int* bar() {int x;
cin >> x;// Let’s say x got 5
return &x;}
int main() {int *ptr = bar();cout << "*ptr = " << *ptr << endl;
}
5
stack
bar()
calls
0x05
main() ptr ??
x 0x00 0x00 0x00
0xbfffedb4? ?
0xbfffecd0top of stack
Data Structures - CSCI 102
Stack VariablesSometimes stack variables can be really inconvenient
int* bar() {int x;
cin >> x;// Let’s say x got 5
return &x;}
int main() {
stack
returned 0x05
0xbfffedb4main() ptr 0xbf 0xff 0xec 0xd0
int *ptr = bar();cout << "*ptr = " << *ptr << endl;
}
Why wouldn’t this print out 5?
6
0xbfffecd00x00 0x00 0x00
top of stack
Data Structures - CSCI 102
Stack VariablesSometimes stack variables can be really inconvenient
int* bar() {int x;cin >> x;
// Let’s say x got 5return &x;
}
int main() {
operator<<()
calls
?????
0xbfffedb4main() ptr 0xbf 0xff 0xec 0xd0
0xbfffecd0
int *ptr = bar();cout << "*ptr = " << *ptr << endl;
}
Why wouldn’t this print out 5?Because that part of the program stack gets recycled!
7
top of stack stack
Sometimes stack variables can be really inconvenient
8
Data Structures - CSCI 102
Copyright © William C. Cheng
Stack Variables
int* bar() {int x;cin >> x;
// Let’s say x got 5return &x;
}
What if we want the pointer to x to stick around long afterbar() has been called?
What if we don’t want C++ to manage memory for us?Use dynamically allocated data structures to manage dataourselves
By default all variables go on the stack
You MUST clean up after yourself!
The heap is large pool of free memory in your C++application that is used for dynamic variable allocation
9
Data Structures - CSCI 102
Copyright © William C. Cheng
Heap Variables and the new Operator
You must explicitly allocate variables on the heap
The heap is not automatically memory managed for youlike the stack is
The C++ operator new can be used to dynamically createnew variables on the heap
When you use the new operator, you’re telling C++ thatit should NOT manage memory for you
Since you’re dynamically creating variables on the fly,their location is not known in advance
The new operator returns a pointer to the new memory ithas allocated
10
Data Structures - CSCI 102
The new Operator
Create a pointer to a new integer on the heap:int* x = new int;*x = 55;
Or all in one statement:int* x = new int(55);
bar()
calls
main() ptr ??0xbfffedb4
? ?
0xbfffecd0x 0x08 0x04 0xb0 0x08
int *x = new int;cin >> *x;// Let’s say x got 5return x;
}
int main() {int *ptr = bar();
...}
11
Data Structures - CSCI 102
The new OperatorUsing a heap variable
int* bar() {0x804b0080x00 0x00 0x00 0x05
heap
stacktop of stack
bar()
calls
main() ptr ??
x
0xbfffedb4? ?
0xbfffecd0
int *x = new int;cin >> *x;// Let’s say x got 5return x;
}
int main() {int *ptr = bar();
...}
12
Data Structures - CSCI 102
The new OperatorUsing a heap variable
int* bar() {0x804b0080x00 0x00 0x00 0x05
heap
stacktop of stack
returned0xbfffecd0
x 0x08 0x04 0xb0 0x08top of stack
int *x = new int;cin >> *x;// Let’s say x got 5return x;
}
int main() {int *ptr = bar();
...}
0xbfffedb4main() ptr 0x08 0x04 0xb0 0x08
13
Data Structures - CSCI 102
The new OperatorUsing a heap variable
int* bar() {0x804b0080x00 0x00 0x00 0x05
heap
stack
returned0xbfffecd0
x 0x08 0x04 0xb0 0x08top of stack
0xbfffedb4main() ptr
int *x = new int;cin >> *x;// Let’s say x got 5return x;
}
int main() {int *ptr = bar();
...}
14
Data Structures - CSCI 102
The new OperatorUsing a heap variable
int* bar() {0x804b0080x00 0x00 0x00 0x05
heap
stack
Binkyhttp://cslibrary.stanford.edu/104/
15
Data Structures - CSCI 102
The new Operator
When you use the new operator, you’re telling C++ that youwill manage your own memory
16
Data Structures - CSCI 102
The delete Operator
If you use new to allocate memory like this:int* x = new int(55);
Then later you must use delete to clean up the previouslyallocated memory like this:
delete x;
The delete operator only marks heap memory as free to beused again, it does not actually destroy it!
delete does NOT change where x is pointing
17
Data Structures - CSCI 102
The delete Operator
If you use new to allocate memory like this:int* x = new int(55);
cout << "X = " << *x << endl;delete x;//what will the following do?cout << "X = " << *x << endl;
It’s a good idea to set pointers to NULL when you’re doneusing them
NULL essentially says "this pointer points nowhere"delete x;x = NULL;
What if you start using new, but you forget to add theassociated calls to delete?
This is called a memory leak
18
Data Structures - CSCI 102
The delete Operator
If you keep allocating memory from the heap using new andnever use delete to clean up, you will eventually run out ofmemory!
Not a big problem for small, short-lived applications, but amajor problem for code that’s going to run for a long time
This will eventually make your application crash
All memory allocated using new is eventually returnedwhen your application terminates (whether you used deleteon it or not)
19
Data Structures - CSCI 102
Other Notes on new and delete
You can also use new to dynamically create arrays:int* values = new int[100];
Dynamic arrays can even be sized based on variablesint size = 256;
int* values = new int[size];
Deleting dynamic arrays looks slightly differentdelete []values;
From this point on, memory block starting at addrbelongs to the user/application
Memory Allocator is defined by its interface
40
Data Structures - CSCI 102
Memory Allocator
new eventually will invoke malloc()delete eventually will invoke free()
addr = malloc(size) - to allocate a contiguous blockof memory of size bytes long
From this point on, memory block starting at addrbelongs to the memory allocator again
Memory allocator must not touch it any morefree(addr) - return memory block starting at addr to thememory allocator
User/application must not touch it any more
Siz
e of
hea
p
Data Structures - CSCI 102
Memory AllocatorInitially, the memory allocator was given a large block of
memory to manageIn a real memory allocator,this is the entire heap space
Memory Allocator
Begining of heap
It has a starting addressand a size
41
42
Data Structures - CSCI 102
Memory AllocatorInitially, the memory allocator was given a large block of
memory to manageIn a real memory allocator,this is the entire heap space
Memory Allocator
Begining of heap
Return the address of the block to the user
It has a starting addressand a size
User/application
busyUser Pointer
When malloc(size) is called,the allocator finds a contiguousblock of memory size byteslong, mark it busy/in-use
43
Data Structures - CSCI 102
Memory AllocatorInitially, the memory allocator was given a large block of
memory to manageIn a real memory allocator,this is the entire heap space
Memory Allocator
Begining of heap
memory
It has a starting addressand a size
User/application
free
When free(addr) is called,the allocator makes the blockfree so it can be allocated later
The block is merged with the rest of the free
User/application code can corrupt the memory allocationchain easily
As you can see, one mistake in the memory allocator codeand your blocks are all messed up
60
Data Structures - CSCI 102
Dynamic Memory Allocation
The result can lead to segmentation faultsUnfortunately, the corruption can stay hidden for along time and eventually lead to a segmentation fault
Memory corruption bugs are very difficult to squash
Now that we have a pointer member variable, how do ourconstructors change?
20
Data Structures - CSCI 102
The Point Class
class Point {private:
int x;int y;int* z;
public:Point();
Point(int newx, int newy, int newz);};
What happens to the memory allocated by new when ourclass is destroyed?
21
Data Structures - CSCI 102
The Point Class
Point::Point() {x = 0;y = 0;z = new int;*z = 0;
}
Point::Point(int newx, int newy, int newz) {x = newx;y = newy;
z = new int(newz);}
22
Data Structures - CSCI 102
C++ Classes: DestructorsA class’s destructor is called when:
1) a stack object goes out of scope2) a heap object is freed from the heap (by delete)It can also be invoked directly (e.g., inside STL code,inside delete, inside delete[])
DestructorCan have one or noneIf class has no destructor, C++ will make oneNo return valueHas the name ~ClassName()
Why use it?Not necessary in simple casesClean up resources that won’t go away
automatically (e.g. stuff you used new to create)
23
Data Structures - CSCI 102
The Point Class Destructor
class Point {private:
int x;int y;int* z;
public:Point();
Point(int newx, int newy, int newz);~Point();
};
Point::~Point() {delete z;
}
1) Memory block of sizeof(Foo) bytes allocated fromheap and its address returned and assigned to ptr
24
Data Structures - CSCI 102
C++ Classes: DestructorsAssume that you started with:
Foo *ptr = new Foo();
delete ptr;What happens when you call:
1) Foo::~Foo() will be called2) Memory block located at ptr will be deallocated
Two things happens
2) Foo::Foo() called
Two things happens
25
Data Structures - CSCI 102
C++ Classes: DestructorsAssume that you started with:
Two things
Foo *ptr=new Foo[5];
delete[] ptr;What happens when you call:
1) Foo::~Foo() will be called 5 times, once for eacharray element
2) Memory block located at ptr will be deallocated(done only one time)
for (int i=0; i < 5; i++) {Foo *p=&ptr[i];
p->~Foo(); //looks weird, but accurate!}
26members?
Data Structures - CSCI 102
Shallow vs. Deep CopyFor all classes, C++ defines a basic capability to copy aclass
By default, class data is just copied member-by-memberfrom one instance to another
Point p1(100,100);Point p2 = p1;
In the second statement, C++ essentially does this:p2.x = p1.x;p2.y = p1.y;
This is called making a shallow copyA straight foward memory to memory copy:
memcpy(&p2, &p1, sizeof(Point));This may not be what you want!
What happens if the Point class contains pointer
Let’s try this again:
27
Data Structures - CSCI 102
Shallow vs. Deep Copy
Assume the class Point has three members:p2.x = p1.x;p2.y = p1.y;
p2.z = p1.z; //this is pointer assignment!
After the shallow copy, p2.z and p1.z are now pointing tothe same integer in memory!Sometimes, this is exactly what you wantSometimes, this is not what you wantOnly you know which behavior you want
28
Data Structures - CSCI 102
Shallow vs. Deep CopyWhen our class contains pointers, we must force C++ to doa deep copy, if appropriate
A deep copy is smart enough to copy the actual data, notjust the variable values
How do we make a deep copy?p2.x = p1.x;p2.y = p1.y;p2.z = new int(*(p1.z)); //makes a new pointer!
After the deep copy, p1 and p2 have separate pointersThe pointers are different
p1.z != p2.zThey point to two instances of same value in this example
*(p1.z) == *(p2.z)
But who is doing the deep copy?
29an object!
Data Structures - CSCI 102
The Copy ConstructorWhen you declare an object, you can initialize it to anotherobject like this:
string original("Hello world!");string my_copy(original);
By default, a simple copy constructor is provided for youby the compiler
It just blindly copies values from the original to the copymember by member (a shallow copy)
Point original(12,30);Point my_copy(original);//this works too!Point another_copy = original;
Using memcpy()
Copy constructors are only called during creation of
Remember that when we pass something "by value" to afunction, C++ makes a copy
30
Data Structures - CSCI 102
The Copy Constructor
void foo(Point c) {...}
The copy constructor is responsible for making copies ofobjects that get passed "by value"
class Point {public:
Point(const Point& original) {x = original.x;y = original.y;
z = new int(*(original.z));}
}};
What does a copy constructor look like?
If the default member-by-member copying works, whywould we define our own?
31
Data Structures - CSCI 102
The Copy Constructor
If some data should not be copiede.g. You have a member variable that stores the timethe object was created
If you have pointersBy default, the pointer itself will be copied (NOT thething it’s pointing to!)You will end up with two pointers both pointing to theexact same value in memory!
This is IMPORTANT
Again, sometimes, this is exactly what you want;sometimes, this is not what you want. Only youknow which behavior you want
So if copy constructors only take care of object creation,what about the ’=’?
32
Data Structures - CSCI 102
The ’=’ Operator
Point c1(12,30);Point c2(0,0);
//this doesn’t call the copy constructorc2 = c1;
By default, this compiles and works, but what’s going on?The ’=’ does the same member-by-member copy, but viaa different method (a shallow copy)
Using the default ’=’ will have the exact same problems asthe default copy constructor!
Using memcpy()
So how can we make this work?
33
Data Structures - CSCI 102
The ’=’ Operator
Point c1(12,30), c2(0,0);c2 = c1;
Overload the assignment operator
Things to consider
Point& Point::operator=(const Point &other)
Why does it return a Point&?It must be implemented as a member function
Other notesIt should end with:
return *this;
34
Data Structures - CSCI 102
The ’=’ Operator
Point& Point::operator=(const Point &other){
//what is the purpose of this if?if (this != &other) {x = other.x;y = other.y;
z = new int(*(other.z));}
//what is the purpose of this return?return *this;
}
Destructor
Good C++ coding dictates that if you find that you have tocreate any of these for your class:
35
Data Structures - CSCI 102
The Rule of 3
Copy ConstructorAssignment Operator (=)
The things that force you to implement one of them (e.g.pointer member variables) affect all of them
Then you should make sure you implement all three ofthem!
You can get into big trouble if you have a destructor, butno copy constructor or = operator
Unless you are extremely careful (and have a habit ofnever using automatic variable of this class)