Channels ▼

Andrew Koenig

Dr. Dobb's Bloggers

Avoid New and Delete for Dynamic Arrays

May 04, 2011

This note continues the discussion I started last month about teaching C++. In it, I have been advocating the standard vector template instead of built-in arrays.

One nice attribute of vectors is that you don't need to know the length of a vector during compilation. However, some people argue — and I've seen teachers and textbooks that advocate — using new and delete expressions as an alternative to arrays.

On the surface, new and delete expressions are almost as easy to use as vectors. For example, instead of writing

int size;
cin >> size;
int numbers[size]; // C++ does not allow this

you can write

int size;
cin >> size;
int* numbers = new int[size];

to allocate a dynamic array with size elements. And indeed, this example isn't much more complicated than writing

int size;
cin >> size;
vector<int> numbers(size);

at least not on the surface. Of course, if you're going to use new, you should use delete as well, so the code should really look like this:

int size;
cin >> size;
int* numbers = new int[size];

...

delete[] numbers;

In this example, the teacher must explain why delete is needed for numbers even though it's not needed for size; why the definition of numbers has to mention int twice; why the * is there; and why delete needs the [] after it. Still, on the surface, this code doesn't look like it's much harder than the corresponding code that uses arrays.

The trouble is that code that looks simple on the surface can conceal deeper problems, and these problems can encourage students to think in ways that are less useful than they might be. For example, the code examples I've written so far do not occur in isolation. Rather, any executable code must be part of a function. Let's sketch at least the outline of that function:

int main()
{
int size;
cin >> size;
int* numbers = new int[size];

...

delete[] numbers;
return 0;
}

We can now see that we allocate memory for our dynamic array at the beginning of main and free it at the end. What happens if the code represented by ... contains a return statement?

The answer is that the memory that we allocated is never freed. Of course, the operating system will free that memory for us — so long as main is the function involved. But now our students are encouraged to think that failure to free memory is acceptable. If the code is later moved from main

Although using new lets you defer setting the size of an array until runtime, programmers sometimes want to change an array's size after it has already been allocated. Suppose, for example, that we want to change the number of elements in numbers from size to newsize. We might do so as follows:

int newsize;

// Allocate space for the new array
int* newnumbers = new int[newsize];

// Copy the elements of the old array
for (int i = 0; i < size; ++i)
newnumbers[i] = numbers[i];

// Free the old array and reset the pointer delete[] numbers;
numbers = newnumbers;

We have just used six lines of code to accomplish what we could have done in a single line if we were using vectors:

numbers.resize(newsize);

Moreover, these six lines of code conceal a serious bug, which I am leaving to you as an exercise to find.

Probably the most common reason to want to change the size of a dynamic array is to append a single element to it. Of course, the standard vector template makes it both easy and efficient to do so:

numbers.push_back(newnumber);

One might think that this operation would be horrendously slow, because it must copy the entire vector each time we want to append an element. However, vectors quietly allocate more memory than is strictly needed, and use that memory to give the vector room to grow. Only when the vector outgrows its memory does it ask for more. There is no direct support in C++ for using new and delete to allocate extra space in this way; vector does so by using different memory-allocation facilities. Therefore, if you were to try to imitate this behavior using new and delete, you would quickly find yourself in trouble.

In short, even though it may seem at first that new and delete are an alternative to built-in arrays that is almost as convenient as using the vector template, vectors have several significant advantages over new and delete. They take care of freeing memory automatically; they make it easy (and less error-prone) to change the size of a vector after it has been allocated; and they manage memory more efficiently than it is possible to do by using new and delete.

Of course, new and delete have their place; but that place is not substituting for built-in arrays or vectors. In fact, I think that it is wise for most C++ programmers to avoid using new and delete with arrays altogether, reserving them for dealing with objects that need to outlive the scope that created them.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video