39

I have allocated and array of Objects

Objects *array = new Objects[N];

How should I delete this array? Just

delete[] array;

or with iterating over the array's elements?

for(int i=0;i<N;i++)
    delete array[i];
delete[];

Thanks

UPDATE:

I changed loop body as

delete &array[i];

to force the code to compile.

Scooter
  • 6,802
  • 8
  • 41
  • 64
osgx
  • 90,338
  • 53
  • 357
  • 513
  • will this be array of pointers or pointer to array? – osgx Mar 21 '10 at 05:23
  • 4
    Doing this: 'delete &array[i];' is incorrect. You did not use new to allocate the element array[i] so you should not delete it. Delete the whole array. – Martin York Mar 21 '10 at 08:40

5 Answers5

55

Every use of new should be balanced by a delete, and every use of new[] should be balanced by delete[].

for(int i=0;i<N;i++)
    delete array[i];
delete[] array;

That would be appropriate only if you initialized the array as:

Objects **array = new Objects*[N];
for (int i = 0; i < N; i++) { 
    array[i] = new Object;
}

The fact that your original code gave you a compilation error is a strong hint that you're doing something wrong.

BTW, obligatory: avoid allocating arrays with new[]; use std::vector instead, and then its destructor will take care of cleanup for you. Additionally it will be exception-safe by not leaking memory if exceptions are thrown.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • 37
    No! Don't use std::vector blindly as a substitute for arrays! That's like saying "I have a transportation need, so I'll use a car." Sometimes it's the right answer, but sometimes you need to go next door, and sometimes you need to go from Montreal to Moscow. In many cases where an array is close to the right answer but you want a standard-library, std::valarray is what you want. And in many cases an array is, in fact, the right answer. – Brooks Moses Mar 21 '10 at 05:53
  • 8
    @Brooks. I can think of any situation where a dynamically allocated array can not be replaced efficiently with a std::vector. This is because a std::vector __IS__ an array (the only difference is that the vector handles all the memory management). If it is a statically allocated array fine you may get a tiny performance improvement with just using an array. – Martin York Mar 21 '10 at 08:47
  • Technically, `std::vector` is **not** an array, but a class (why do you say that it is an array, but then say "the only difference is"?). But non-technically (speaking loyally) it is an array because the usage is similarly. – Johannes Schaub - litb Mar 21 '10 at 14:29
  • @райтфолд While yes, the `new[]` example I gave would leak if exceptions are thrown, I *never* endorsed initializing that way: I said, "If you initialized the array as...". I will amend my `std::vector` recommendation to emphasize the exception safety aspect, though. – jamesdlin Mar 27 '15 at 21:00
  • @BrooksMoses: +1 for mentioning `std::valarray`. std::vecotr is not just a pointer plus new/delete: it also track size, capacity and what required to grow and shrink. What an array, once allocated, don't and valarray also doesn't, making it structurally simpler. – Emilio Garavaglia Mar 27 '15 at 21:14
  • Funny... I get a crash by calling `delete[]`. And I'm creating an array of objects exactly like that. I think whether it works depends on the class. – Paulo Carvalho Jun 25 '17 at 11:05
  • @PauloCarvalho No, it doesn't depend on the class. It depends on whether the array was created with `new[]`. If `delete[]` crashes when destroying a `new[]`-allocated array, you're doing something else wrong (such as corrupting your heap). – jamesdlin Jun 25 '17 at 11:27
19

Just delete[] array is sufficient. It is guaranteed that each element of the array is deleted when you delete an array using delete[] operator.

Naveen
  • 74,600
  • 47
  • 176
  • 233
14

As a general rule you should delete/delete[] exactly those things that you allocated with new/new[]. In this case you have one allocation with new[], so you should use one call to delete[] to free that allocated thing again.

That the deletes in the for-loop won't compile is also a good indication that they are not the right way to do it.

sth
  • 222,467
  • 53
  • 283
  • 367
9

Not only is

delete [] array;

enough, but if you do

for(int i=0;i<N;i++)
    delete &array[i];
delete[] array;

you'll be causing undefined behavior, because

delete &array[i];

will be deleting things that weren't returned by a new operation.

Not to mention that the subsequent delete[] array; will call the destructor for all the objects that just had destructors called in the loop.

So don't do that.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
8
delete [] array

is enough.

vava
  • 24,851
  • 11
  • 64
  • 79