12

I'm new to C++, and I'm confused about arrays and pointers. Could someone tell me how I can properly delete a pointer. Like for example,

int *foo;
foo = new int[10];

delete foo;

or

delete [] foo;

Thanks.

2
  • if all the answers are correct how can i accept it all, i dont like choosing only one, since all them are nice to answer my question? Commented Sep 27, 2009 at 23:19
  • You cannot accept all. You can up-vote all if you found all of them helpful, but you should accept one. Criteria for acceptance are suggested in the FAQ, but might include correctness, usefulness, completeness, etc. Commented Sep 27, 2009 at 23:23

6 Answers 6

21

The requirement to match new[] with delete[] is technically correct.

Much better, however (at least in my opinion), would be to forget that you ever even heard of new[], and never use it again. I'm pretty sure it's been (at least) 10 years since the last time I used new[], and if I'd understood the situation very well, I'd have stopped even sooner than that. Pretty nearly any time you'd even consider using new[], an std::vector (or possibly std::deque) will be a better choice.

If you're trying to create something roughly equivalent to a vector or deque yourself, you don't normally want to use new[] for that either. They way they (at least normally, though it's possible to change this via a custom Allocator class) is to allocate "raw" storage with operator new (which is pretty much like malloc--you just give it a size, and it gives you that many bytes of storage). Then you use the placement new operator to create objects in that space, and explicitly invoke the object's destructor to destroy objects in that space.

To give one example, this is what allows std::vector to support reserve, which allows you to allocate extra space, which won't be turned into objects until you call something like push_back or emplace_back to create an actual object in the space you allocated.

When you use new[], it has to create objects of the specified type filling all the space you allocate. You can't create something like push_back that adds a new object to the collection, because the collection is always already "full". All you can do is allocate a new collection that's larger than the old one (so every addition to the collection is O(N) instead of the amortized O(1) supported by std::vector--a huge loss of efficiency).

Sign up to request clarification or add additional context in comments.

2 Comments

What if you were trying to build a string class, or something useful like that? Blanket bans on new are bad.
The blanket ban would be on new[], not on new. A collection class (including a string) should invoke ::new(size_t); directly. When you use new[], it creates an array of objects -- i.e. all those positions are allocated AND constructed. A collection should NOT create objects in the empty space (merely pointless for a string, positively harmful if the objects are expensive to construct). Instead, it should allocate uninitialized storage, and then use placement new to create objects in that storage.
10

It's:

delete[] foo;

Edit: Modern compilers really need you to use the correct delete operator, or they may leak memory or fail to run the proper destructors.

(I earlier stated that it didn't make a difference in practice. About 10 years ago, I tried many different compilers and failed to find one that actually leaked memory if you mistakenly omitted the []. However the howls of the mob - see below - have forced me to re-try my experimentation, and it seems that modern compilers/libc++s really do care.)

7 Comments

Even if compilers do the right thing with delete, I think using delete [] is still better practice -- both for cases where you run into compilers that do not do the right thing, but also as a declaration of intent.
Compilers might not leak memory, but they likely won't call destructors without the []...
I don't think I've ever seen a compiler which allows you to use delete when delete[] is expected. They always produce code that blows up when I do it.
@alex: It WILL leak memory. But because you used the wrong delete you have messed up the internal memory structure used by the memory management routines. Thus it is quite possible that the it will not be reported by any tools that try and monitor memory leaks.
They might not leak memory when you use types with trivial dtors. For UDT's with non-trivial dtors, however, this is quite different, because delete won't call all the dtors.
|
5

If you allocate an array of objects using the new [] operator then you must use the delete [] operator and therefore the non-array new can only be used with the non-array delete.

int *a = new int[10];
int *b = new int;

delete [] a;
delete b;

Comments

3

If you do new <type>[] you must do delete []. It's a simple enough rule, and worth remembering.

Comments

2

You walked in the front door and left it open. Then you walked through to the back door and tried to close it but you smashed it because it was already closed.

foo = new int [10];  // so when you open the front door
delete [] foo;       // please remember to close the front door.

foo = new int;       // and when you open the back door
delete foo;          // please remember to close the back door.

Don't mix them up!

Comments

2

Anytime you newed an array you use delete[]. Sometimes you new'ed an array using new - then you still have to use delete[] - no way out. So it's not exactly a rule "use delete[] when you new[]'ed" but rather "use delete[] when deleting an array".

typedef int array[5];

int *a = new array;
delete[] a; // still delete[] !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.