Announcement • Final exam C++: Memory Problems – Tuesday, May 20 th – 2:45 – 4:45pm – Rm 70-1620 or When Good Memory Goes Bad Announcement Announcement • Speaking of exams • First exam – First exam – Types of questions • April 10 th • UML – identify, draw • Will cover – UML • Fill in the code – C++ variables (pointers, references, objects) – No large coding. – Functions/Operators • Memory illustrations – Constructors » copy vs. operator= • Fill in the blanks » Subobject initializer lists • What is right/wrong with this picture? – Inheritance » Inheritance, Polymorphism, & Memory / Slicing Project Projects • Page on using shapewin (with header.mak) • Using shapewin Windows – Is now up – Must qualify with namespace • RITCS::Window • Using shapewin – Also included in ritcs library • Next deliverable – FileImage viewer: due April 18 th
Initializer Lists Initializer Lists • When using initalizer lists in constructors class StudentCounter { private: – Data members get initialized in the order in Student *personArray; int currentMax; which they appear in the .h file and NOT in the … order in which they appear on the list. } StudentCounter::StudentCounter() : currentMax(10), personArray (new person [currentMax]) {} Plan for today Memory Leak • Memory Woes • A bug in a program that prevents it from freeing up memory that it no longer needs. – Memory Leaks – Pointer Ownership • As a result, the program grabs more and more memory until it finally crashes – Dangling Reference because there is no more memory left. – Overwriting Arrays • In short: • “It’s a pointer problem” – Allocating without cleaning up. Memory Leak Memory Leak class Foo Foo::Foo (int size) : asize (size), array_member (new int[size]) { { private: for (int i=0; i<size; i++) int *array_member; array_member[i] = 0; int asize; } ... void f () public: { Foo (int size); // local aClass object ~Foo (); aClass a (20); } ... }
Memory Leak Pointer Ownership • Everything that is a pointer should be owned – Responsible for cleanup when finished aClass a asize array_member – Should be known to programmer 20 – Should be by design during implementation. ints stack – Owner and only owner should perform a delete. heap Pointer Ownership Pointer Ownership // constructor • Class members Foo::Foo (int size) : – If you allocate it during construction, you asize (size), array_member (new int[size]) { should deallocate during destruction. for (int i=0; i<size; i++) array_member[i] = 0; } – Should also deallocate during // destructor • Copy construction Foo:~Foo () • operator= { delete [] array_member; } Pointer Ownership Pointer Ownership // assignment operator // copy constructor Foo &Foo::operator= (const Foo &F) Foo::Foo (const Foo &F) { { if (F != (*this) { if (F != (*this) { delete [] array_member; delete [] array_member; array_member = new int[F.asize]; asize = F.asize; array_member = new int[F.asize]; for (int i=0; i<asize; i++) asize = F.asize; array_member[i] = F.array_member[i]; for (int i=0; i<asize; i++) } array_member[i] = F.array_member[i]; } return (*this); } }
Pointer Ownership Pointer Ownership class Moo • Pointers returned by functions { – Who should be responsible for memory to private: char* myID which these pointers point? static char anotherId[15]; ... public: Moo (); ... char *getID(); } Pointer Ownership Pointer Ownership Allocation done in method…caller should be Allocation done in constructor…object should be responsible for pointer….should deallocate in destructor responsible for pointer. Moo::Moo () : myID (new char[15]) char * Moo::getID() { { strcpy (id, “I am a cow”); char *id = new char[15]; } strcpy (id, “I am a cow”); char * Moo::getID() { return id; return myID; } } Pointer Ownership Pointer Ownership Memory is static…object should be responsible for Memory is static…object should be responsible for pointer but no deallocation necessary pointer but no deallocation necessary char * Moo::getID() char Moo::anotherID[15] = “I am a cow”; { // This is okay too. char * Moo::getID() static char idInFunct[50] = “I am a { cow”; return anotherID; return idInFunct; } }
Pointer Ownership Pointer Ownership Should not return pointer to local variable • Pointers returned by functions – Who should be responsible for memory to which these pointers point? char * Moo::getID() • Either caller or object { • Should be clearly designed and documented // This is not okay. char idInFunct[50] = “I am a cow”; return idInFunct; } Pointer Ownership Pointer Ownership • Anonymous Objects • Anonymous Objects – Beware when anonymous objects are allocated on free – An anonymous object is an object in every store. sense except that it has no name. vector< Card * > hand; – Used for creating very temporary objects. hand.push_back( new Card(...) ); hand.push_back( new Card(...) ); hand.push_back( new Card(...) ); Point square[] = : : {Point(0,0),Point(0,1),Point(1,1),Point(1,0) }; If vector does not take ownership of the objects stored in it, a memory leak is possible. Memory Leak / Pointer Dangling Pointers Ownership • Pointer is pointing to something that it • Questions? shouldn’t be. • Can happen if: – If the scope of a pointer extends beyond that of the object being pointed to • i.e Returning a pointer to a local variable. – If a dynamically allocated memory cell is freed explicitly and then the pointer pointing to such a space is used in subsequent code.
Dangling Pointers Dangling Pointers • Ways to prevent dangling pointers p1 = new Foo; : – Do not return pointers to local variables. delete p1; – After calling delete on a pointer, : immediately set it to NULL. p2 = new Bar; // What if same memory is //given to p2? p1 = new Foo; : delete p1; int i = p1->data; // i contains garbage p1 = 0; p2 = new Bar; p1->op(...); // p2's object mysteriously p1->op(...); // core dump! changes! Overwriting Arrays Overwriting Arrays void foo() • Recall that C++ has no array bounds { checking. int *a = new int[20]; aClass *b = new aClass(); – Writing past bounds of array will trash ... a unsuspecting memory. a[20] = 23; // b mysteriously // changes b } heap Overwriting Arrays Overwriting Arrays • This can be quite dangerous for local arrays: void foo() Local Variables { int a[20]; a[20] = 23; a Local Variables } Return Address Return Address Function Arguments Function Arguments
Dangling Pointers / Overwriting Arrays Overwriting Arrays void foo() • Questions? { char a[20]; strcpy (a, “This string is too long”); } Getting around these problems Getting around these problems • The smart pointer • The smart pointer – Prevents memory leaks and dangling pointers – Wrapper class that owns a pointer to an object • But more on this tomorrow… • Object keeps a reference count of variables accessing it • When the reference count reaches 0, the object is deleted by the smart pointer. • Questions? • After deleting object, pointer value set to 0.
Recommend
More recommend