200 likes | 295 Views
Pointers Revisited. What is variable address, name, value? What is a pointer? How is a pointer declared? What is address-of (reference) and dereference operators? How can a pointer be assigned a value? How can a value of a memory location referred to by a pointer be accessed?
E N D
Pointers Revisited • What is variable address, name, value? • What is a pointer? • How is a pointer declared? • What is address-of (reference) and dereference operators? • How can a pointer be assigned a value? • How can a value of a memory location referred to by a pointer be accessed? • What is a constant pointer? What is a pointer to a constant? • What is the relationship between array name and a pointer? • What is the operation to move pointer to the next/previous memory location? • What is null pointer? What is lose pointer problem? • Can pointers be used with objects? How can a method be invoked on an object using pointer? • what is -> operator?
Why Dynamic Memory • when a variable is declared - a certain memory area (sufficient to hold the variable of this type or class) is allocated • not all memory can be allocated or efficiently allocated at the compilation time • we are manipulating an set of data of arbitrary size • what if we allocate an array too small? • what if we allocate an array too large? • dynamicmemory allocation – memory allocation at execution time under the direct control of programmer • dynamic memory allocation is more flexible since the program can claim and release memory as needed and potentially can get as much memory as the computer resources allow • heap - the system structure where the memory is allocated • heap is separate for every program and it is removed when the program finishes
new and delete • new and delete - operations used to dynamically manipulate memory • new - allocates a nameless variable of specified type (or class) and returns a pointer to it int *ip; // declare pointer ip = new int; // ip points to integer var • note that the variable has no name and the only way to access the variable is though as pointer: cin >> *ip; *ip += 20; cout << *ip; • new may take a parameter to initialize the variable with ip = new int(5); // 5 assigned to the var • delete - releases memory back to heap so that it can be reused delete ip; • note - the memory pointed to by ip goes away not the pointer variable itself • memory allocation types • static variable/constant – location known at compile time: literal constants, global variables, allocated in special place for static vars. • automatic variable – with scope: local variables, parameters, temp. variables, allocated on stack • dynamic variable - created with new,allocated in heap
Memory Leak Problem • note that the pointer that points to the dynamic variable is the only way to access this variable • if the pointer is reassigned the dynamic variable is “lost”. This is called a memory leak problem int *ptr = new int; ptr = new int; // error - memory leak • is this a memory leak? int *ptr1,*ptr2 = new int; ptr1=ptr2; ptr2 = new int; • does this code have a problem? int *ptr = new int; delete ptr; *ptr=5;
Pointers and Arrays • array name is equivalent to: base_type * const • that is array name is a pointer that cannot be changed • array name points to the first element of the array • array name can be used as pointer • pointer can be used as an array name int a[10], *p1, *p2; p1=a; // where does p1 point now? p1[2]=5; // which element does p1 access a=p2; // is this legal? p1[20]; // is this legal?
Dynamic Arrays • arrays can be created dynamically just as scalar variables. • newhas to be passed the number of elements of the array int *p1, *p2, num; p1=new int[10]; • the number of array elements need not be constant: cin >> num; p2=new int[num]; p2= new int[0]; // operates correctly, sometimes useful • new returns the pointer to the first element of the dynamically allocated array. This pointer can be used just like regular array name: p1[2]=42; • note, unlike regular array name, this pointer can still be changed p1=p2; • delete has special syntax for array deallocation: delete [] p1; • note that the pointer passed to delete does not have to be the same that receives the value returned by new • how does the computer know how many elements to delete? – part of dynamic array implementation
Pointers and Functions • Pointers can be passed as parameters to and returned by functions // passing pointer by value void funcVal(int *p){ *p = 22; p = new int(33); } // passing pointer by reference void funcRef(int *& p){ *p = 44; p = new int(55); } // passing pointer to pointer, superseded by above: seldom used void funcRefRef(int **pp){ **pp = 66; *pp = new int(77); } // returning pointer int *funcRet(){ int *tmp = new int(88); return tmp; }
0 1 2 3 4 p these locations cannot be accessed by program 0 1 2 3 4 p — — — — — Memory Leak with Dynamic Arrays int *p = new int [5]; for (int i = 0; i < 5; ++i) p[i] = i; p = new int [5];
Dynamic Objects • objects can be allocated dynamically class myclass { public: myclass(int n){data=n;} int getdata() const {return data;} private: int data; }; • the object of class myclass can be allocated as follows: myclass *mp1; mp1 = new myclass(5); • when new is passed parameter - constructor is invoked • the object can then be used as regular object: cout << mp1->getdata(); • and destroyed: delete mp1;
Objects Containing Dynamic Members • if we want to create an object that can shrink and grow as needed? class MyClass{ public: MyClass(int); // constructor private: int *d; int size; }; • with the following constructor: MyClass::MyClass(int n){ size=n; d = new int[size]; } • then the following declaration MyClass myobj(5); creates an object containing an array of 10 integer variables MyClass myobj2(10); // 10-element array
Destructor • however, when myobj goes out of scope, the dynamically allocated array is leaked • destructor is a function that is called (automatically) when object goes out of scope class MyClass{ public: MyClass(int); // constructor ~MyClass(); // destructor private: int *d; int size; }; • name of destructor tilde (~) and name of class MyClass::~MyClass(){ delete [] d; } • no need to deallocate automatic variables • destructor is never called explicitly and does not accept parameters • note that destructor is called on every local object when function finishes
Copy Constructor • what if we have this function (note that the object is passed by value): void myfunc (MyClass); • if we invoke it as follows myfunc(myobj);what happens? • the function is passed a reference to the same array - copy of the array is not created • copy constructor is invoked automatically when a new copy of an object is implicitly created • when function is passed an object by value • when function returns an object • copy constructor can be used explicitly • copy constructor is not called when one object is assigned to another (more on that later)
Copy Constructor (cont.) • copy constructor is a constructor that accepts an object of the same class passed by reference class MyClass{ public: MyClass(int); // regular constructor MyClass(const MyClass&); // copy constructor private: int *d; int size; }; • defined as follows MyClass::MyClass(const MyClass& org){ size=org.size; d = new int[size]; for(int i=0; i< size; ++i) d[i]=org.d[i]; } • note that copy constructor can access private members of the parameter object • can be invoked explicitly: MyClass newobj(myobj);
Assignment Overloading • what do you think this operation does? secondObj=firstObj; • copies the value of pointer leaking the array of the old object and not creating a copy of the array in the new object • assignment needs to be overloaded • assignment overloading operator accepts by reference the object on the right-hand-side of equation and is invoked by the object on the left-hand-side class MyClass{ public: … void operator= (const MyClass&); private: int *d; int size; }; • can define as follows (not quite right yet): void MyClass::operator= (const MyClass& rhs){ size=rhs.size; delete [] d; d=new int[size]; for (int i=0; i < size; ++i) d[i]=rhs.d[i]; }
Self-Assignment Protection • what happens if you do this assignment? myobj=myobj;It is legal in C++. Is our overloaded assignment going to handle it right? • this is a reserved keyword. It is a pointer to the object that invokes the member function. It is passed implicitly to every member function • assignment overloading (still not quite right): void MyClass::operator= (const MyClass& rhs){ if (this != &rhs){ // if not same size=rhs.size; delete [] d; d=new int[size]; for (int i=0; i < size; i++) d[i]=rhs.d[i]; } }
Stackable Assignment • what happens if you do this assignment? thirdObj = secondObj = firstObj; • here is the definition that gets above code to work correctly MyClass& MyClass::operator= (const MyClass& rhs){ if (this != &rhs){ // if not same size=rhs.size; delete [] d; d=new int[size]; for (int i=0; i < size; i++) d[i]=rhs.d[i]; } return *this; // return lhs } • note the return value of the function, it is a reference to an object • returned object refers to object used in return-statement • similar to pass-by-reference parameter • seldom used in C++, more common in pointerless-languages (Java, C#)
The BIG Three • big three - copy constructor, overloaded assignment and destructor • expert opinion - if you need any one of them - most probably you will need all three • they are not syntactically related but it is usually safer to define all three if you think you’d need at least one
Dynamic Memory Review • What is static, automatic, dynamic variables? Why are dynamic(ally allocated) variables needed • What is program stack? Function (invocation) frame? • What is a heap? how is it used? • What is new and delete operations? How are they used? • How does one access a dynamically allocated variable? How does one assign a value to such variable at declaration time? • What is memory leak? • How are dynamic arrays allocated? deallocated? • How can a pointer be passed by value/by reference to a function? • What are dynamically allocated objects? Objects containing dynamically allocated members? What may be potential problems with the latter? • What are the big three operations? • What is a destructor? Why is it needed? When is it executed? How is it declared/defined? • What is a copy-constructor? Why is it needed? When is it executed? How is it declared/defined? • What is operation overloading? What is overloaded assignment? Why is it needed for objects with dynamic members? How is it declared/defined? • What is this-pointer? What is protection against self-assignment? How is this-pointer used for that? • What is stackability of an operator? How can overloaded assignment be made stackable?