80 likes | 355 Views
Overview of Memory Layout in C++. 4 major memory segments Global: variables outside stack, heap Code (a.k.a. text): the compiled program Heap: dynamically allocated variables Stack: parameters, automatic and temporary variables Key differences from Java
E N D
Overview of Memory Layout in C++ • 4 major memory segments • Global: variables outside stack, heap • Code (a.k.a. text): the compiled program • Heap: dynamically allocated variables • Stack: parameters, automatic and temporary variables • Key differences from Java • Destructors of automatic variables called when stack frame where declared pops • No garbage collection: program must explicitly free dynamic memory • Heap and stack use varies dynamically • Code and global use is fixed • Code segment is “read-only” stack heap code global
#include <iostream> using namespace std; int main (int, char *[]) { int * i = new int; // any of these can throw bad_alloc int * j = new int (3); int * k = new int[3]; int * l = new int[*j]; for (int m = 0; m < *j; ++m) { l[m] = m; } delete i; delete j; delete [] k; delete [] l; return 0; } Dynamic Allocation and Deallocation Array vs. single instance new Fill in array values with loop Array vs. single instance delete
Copy and paste (or type) this code into Visual Studio (or emacs on grid) Add an appropriate try-catch block around the statements that can throw an exception Before you can build, what other statements must also go into the try-catch block? Why? Print all the elements of each dynamic allocation before it’s destroyed Exercise #include <iostream> using namespace std; int main (int, char *[]) { int * i = new int; int * j = new int (3); int * k = new int[3]; int * l = new int[*j]; for (int m = 0; m < *j; ++m) { l[m] = m; } delete i; delete j; delete [] k; delete [] l; return 0; }
Temporary variables Are scoped to an expression, e.g., a = b + 3 * c; Automatic (stack) variables Are scoped to the duration of the function in which they are declared Dynamically allocated variables Are scoped from explicit creation (new) to explicit destruction (delete) Global variables Are scoped to the entire lifetime of the program Includes static class and namespace members May still have initialization ordering issues (see Singleton Pattern) Member variables Are scoped to the lifetime of the object within which they reside Depends on whether object is temporary, automatic, dynamic, or global Lifetime of a pointer/reference is independent of the lifetime of the location to which it points/refers (e.g., new and delete) Memory, Lifetimes, and Scopes
“Guard idiom” expands on constructor/destructor idiom C++ has an auto_ptr class template (a “generic” programming construct) auto_ptr<X> assumes ownership of a pointer-to-X auto_ptr<X> destructor calls delete on the pointer if the auto_ptr still owns it Call release to break ownership by an auto_ptr<X> (once it’s safe to do so) Foo *createAndInit() { Foo *f = new Foo; auto_ptr<Foo> p(f); init(f); // may throw exception p.release(); return f; } int run () { try { Foo *d = createAndInit(); return 0; } catch (...) { return 1; } } Resource Acquisition is Initialization (RAiI)
auto_ptr<X> copy constructor transfers ownership from the older to the newer one E.g., if you pass an auto_ptr by value to a function E.g., if you create a vector of auto_ptr variables E.g., if you return an auto_ptr by value as a function result Ownership is passed along a chain of responsibility for the memory Makes sure it’s cleaned up once at end of chain auto_ptr<Foo> createAndInit() { auto_ptr<Foo> p(new Foo); p = init(p); // may throw exception return p; } int run () { try { auto_ptr<Foo> q(createAndInit()); // do something with object return 0; } catch (...) { return 1; } } More About auto_ptr and RAiI
Download, compile and run the array_exercise5.cc and array_exercise5.h files Provided on the CSE 232 course web page While we do that we’ll talk about what the program does What does the output tell you about What memory management it’s doing correctly? What memory management it’s doing incorrectly? Please try fixing the things it’s doing incorrectly E.g., making sure all dynamically allocated memory is cleaned up E.g., making sure object constructors get a matching destructor call Please try improving at least one thing that it could be doing better (assuming we still want all the dynamic allocations) E.g., using auto_ptr everywhere it makes sense to use it (but not where it doesn’t make sense to do so) Exercise