The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science
Programming Languages and Tools:
CS:3210:0001
Lecture/Lab #17
Programming with C++
Stack vs heap, pointers, storage duration, dynamic memory allocation
Course project
Stack vs heap
Application code
(Typical, simplified) memory model
Static storage
Stack
Heap
Local variables
Dynamically allocated memory
Global aka namespace variables
0x00000000
0xFFFFFFFF
Stack (automatic storage)
int n; // static storage
void foo( int m ) // automatic storage
{
point p; // automatic storage
}
int main()
{
double d; // automatic storage
int e; // automatic storage
if ( true )
{
bool b; // automatic storage
foo( 42 );
}
}
double d
0xffffffe8
bool b
0xffffffe4
int m
0xffffffe3
point p
0xffffffac
int e
0xffffffa0
Stack
Heap (dynamic storage)
void foo( int* m )
{
point* p = new point;
}
int main()
{
double* d = new double;
int* e = new int;
if ( true )
{
bool* b = new bool;
foo( e );
}
}
double
bool
int
point
0xff000040
0xff000000
Heap
0xff000020
0xff000060
Storage characteristics
Stack
Heap
-
Automatically managed by the compiler
-
Efficient allocation/deallocation
-
Variables can't outlive functions they've been defined in
-
Can't allocate an arbitrary amount of memory that is determined at run time
-
Stack size is limited
-
Memory is never fragmented
-
Explicitly managed by the program author/automatically managed through standard library facilities
-
Generally expensive allocation/deallocation
-
Storage can outlive functions it's been allocated in
-
Prone to fragmentation
-
Can allocate arbitrary amounts of memory that are determined at run time
-
Allocation size is limited only by the amount of free memory available on the particular machine running the program
Pointers vs references
Reference
Pointer
-
An alias to an existing variable
-
Has to be initialized, cannot be re-aliased to another variable
-
Assigning a value modifies the aliased variable:
-
Stores an address of an existing variable or nullptr
-
Can be left uninitialized (but dereferencing uninitialized pointer produces undefined behavior)
-
Can be reassigned a different address:
int i = 17;
int& ref = i;
ref = -10; // i == -10
int i = 17;
int* ptr = &i;
int j = 41;
ptr = &j;
-
Can be dereferenced; dereferencing a pointer gives us a reference:
*ptr = 33; // j == 33, same as:
int& jref = *ptr;
jref = 33;
Exercise 1
Replace question marks with "stack", "heap" or "global", according to your understanding of the language rules
-
Open the exercise template
-
Write your code, press Run to test
-
When you're done, grab your Repl's link and send it as a direct message to me (agurtovoy)
-
Click on the corresponding option in the "Lab17 exercises" poll in #general
new and delete
new type
- attempts to allocate dynamic storage of the specified type
- returns a pointer to type
- can fail with an exception if there isn't enough memory available
- allocated memory is default-initialized (default constructor is called for user-defined types, built-in types are left uninitialized)
new type()
new type( value )
- same as above, but memory is direct-initialized with the provided value (a corresponding constructor is called for user-defined types, built-in types are initialized with the value/zero-initialized if no value has been provided)
delete ptr
- deallocates storage previously allocated by a new
- if ptr points to a user-defined type with a non-trivial destructor, the destructor is called
- has no effect if ptr is a null pointer
Programming with C++, Fall 2019, Lecture #17
By Aleksey Gurtovoy
Programming with C++, Fall 2019, Lecture #17
Stack vs heap, pointers, storage duration, dynamic memory allocation
- 591