CS253: Software Development with C++

Fall 2019

Dynamic Memory

Show Lecture.DynamicMemory as a slide show.

CS253 Dynamic Memory

The old C way

In C, we used functions to allocate & free memory:

They still work, but don’t use them. They’re not type-safe, and they don’t call ctors & dtors (constructors and destructors).

The new C++ way

In C++, we use keywords to allocate & free memory:

You have to delete the memory that you allocate.

Don’t delete it more than once!

Scalar Example

int *p = new int;
*p = 42;
cout << p << ' ' << *p << '\n';
delete p;
0x1d642b0 42

Array Example

int *a = new int[10];
for (int i=0; i<10; i++)
    a[i] = i*11;

for (int i=0; i<10; i++)
    cout << a[i] << ',';

delete[] a;         // Note the []
0,11,22,33,44,55,66,77,88,99,

Match new with delete, and new [] with delete []

If you mix them up, the system might catch your error, or it might not.

Java Error

Java programmers, remember that objects do not have to be dynamically allocated. You can, but you don’t have to.

string s = new string;
c.cc:1: error: conversion from 'std::__cxx11::string*' {aka 
   'std::__cxx11::basic_string<char>*'} to non-scalar type 
   'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} requested

Instead, just declare the string:

string s = "Hi there\n";
cout << s;
Hi there

Sure, the string allocates dynamic memory, internally, but that’s none of your business.

Avoid all of this

In general, use standard containers such as string, vector, or list when you can. They handle the dynamic memory allocation, so you don’t have to.

Besides, code that deals with dynamic memory is easy to get wrong. Code that you write will have bugs. vector, on the other hand, has had its bugs discovered & fixed ages ago.

If you must use dynamic memory, then consider unique_ptr and shared_ptr.

Double Delete

Every call to new must be matched by exactly one delete.

Not zero, and not two. One.

Similarly, every call to new [] must be matched by exactly one delete [].

Zero Delete

If you don’t call delete, then the memory is forgotten. We call this a memory leak.

Sure, the memory will be implicitly freed when the program ends. However, some programs run for a good long time before they end. This program allocates memory every second, and forgets to free it.

// Clock program
draw_clock_face();
while (sleep(1)) {
    GraphicsContext *gc = new GraphicsContext;
    gc->redraw();
    // forget to free GraphicsContext
}

Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip. Drip.

Multiple Delete

What happens if you call delete more than once?

float *p = new float[100];
delete[] p;
delete[] p;
free(): double free detected in tcache 2
SIGABRT: Aborted

Pick Up Your Own Trash