7

After I do, say

Foo* array = new Foo[N];

I've always deleted it this way

delete[] array;

However, sometimes I've seen it this way:

delete[N] array;

As it seems to compile and work (at least in msvc2005), I wonder: What is the right way to do it? Why does it compile the other way, then?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
raven
  • 2,574
  • 2
  • 27
  • 49

7 Answers7

13

You can check this MSDN link: delete[N] operator. The value is ignored.

EDIT I tried this sample code on VC9:

int test()
{
    std::cout<<"Test!!\n";
    return 10;
}

int main()
{
    int* p = new int[10];
    delete[test()] p;
    return 0;
};

Output is: Test!!

So the expression is evaluated but the return value is ignored. I am surprised to say the least, I can't think of a scenario why this is required.

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • does it mean you can delete[2N] array; and that would compile – Vivek Sharma Nov 17 '09 at 11:03
  • 2
    My guess would be that this syntax was valid in a pre-standard dialect of C++, so the "evaluate and ignore" behaviour would be needed for a hypothetical bit of ancient code that depends on a side-effect of the expression. I'm more surprised that support for this syntax would be enabled by default in any modern compiler. – Mike Seymour Nov 17 '09 at 15:56
10

delete [N] array is invalid. It's not defined in the C++ standard: section 5.3.5 defines a delete expression as either delete expr or delete [] expr, and nothing else. It doesn't compile on gcc (version 4.1.2). As to why it compiles in Visual C++: ask Microsoft.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Which C++ standard? And, do you have a link/ref, where one can find it? – Kissaki Oct 03 '11 at 10:55
  • 1
    @Kissaki: I would have been referring to C++03, which isn't legally available online. However, the wording is very similar in C++11, a draft of which is available at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf – Mike Seymour Oct 03 '11 at 11:04
5

delete[] array; is the correct form.

laura
  • 7,280
  • 4
  • 35
  • 43
5

Whether second case is right or not I'd recommend to use first one as it less error prone.

Visual Studio compiles a lot of things it shouldn't.

Mykola Golubyev
  • 57,943
  • 15
  • 89
  • 102
4

The right way is to do delete[] array;. I didn't even know delete[N] array; would compile (and I doubt it should).

sbi
  • 219,715
  • 46
  • 258
  • 445
  • 1
    It compiles on VC9 with a `warning C4208: nonstandard extension used : delete [exp] - exp evaluated but ignored` I don't what that means though – Naveen Nov 17 '09 at 10:48
  • 1
    It means the code is (1) not valid C++, and (2) the expression `N` is evaluated but ignored. That's fairly irrelevant, but it describes what happens if you wrote `delete[N++] array;` - N is first incremented, and then ignored. – MSalters Nov 17 '09 at 14:12
  • Really, it is first ignored and then incremented :) – raven Nov 26 '09 at 17:22
4

First point: there's almost never a good reason to use the array form of new or delete to start with -- use std::vector (or some other container) instead.

Second: back in the dark ages of C++, you had to specify the size of the array you were deleting, so if you used x = new T[N], the matching delete was delete [N] x. The requirement to explicitly specify the size was removed long ago, but some compilers (especially those that care about backward compatibility with ancient code) still allow it.

Unless you really need to remain compatible with an ancient compiler (one that's 20 years old or so) you shouldn't use it. Then again, unless you need to remain compatible with a compiler so old it doesn't support any standard containers, you shouldn't be using the array form of new or delete in the first place. Just stop!

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks for the history lesson. Then, if I had to pass a dynamic array of, say, floats, to a third party libray, which would be The Right Way to do it wih standard containers? – raven Nov 17 '09 at 15:28
  • Use a vector. When you need to pass the address/length, use &vec[0], and vec.size(). – Jerry Coffin Nov 17 '09 at 15:55
  • +1: In the sep '94 draft of the standard the syntax was already 'delete[]'. And in the same year, Design and Evolution (p218) had the comment that this syntax "... proved too error-prone, so the burden of keeping track of the number of elements was placed on the implementation instead." – Richard Corden Nov 17 '09 at 17:42
-2

if it works, it's a nonstandard extension.

delete [] array;   

is the correct form.

delete array; 

will sometimes also work but is implementation dependent (thus wrong).

Nicholaz
  • 1,419
  • 9
  • 11
  • 1
    The behavior of the second form (without the brackets) is clearly defined for non-array pointers. Its behavior for arrays is not. Anyway, I guess that's the reason why somebody voted you down. – Raphaël Saint-Pierre Nov 17 '09 at 13:33
  • 1
    `delete array` doesn't "work" in any sense of the word, unless you mean it doesn't crash the program. It won't reclaim all the memory allocated in the first place, and if it doesn't crash it will only run the destructor on the first object in the array. (Which is also an error if you did `new Foo[0]`.) – Bill Nov 17 '09 at 14:39
  • 1
    @Bill: I wish I could down-vote comments. Your statement might be true sometimes and at other times it might not. See here: http://stackoverflow.com/questions/1553382/1553407#1553407 and my comment here: http://stackoverflow.com/questions/1553382/1553391#1553391 – sbi Nov 17 '09 at 15:28
  • 1
    @Bill: delete array; (without brackets) does delete all elements on *some* implementations (that's what implementation dependent means) and since the example in the question is about int types there are no destructors to be called. – Nicholaz Nov 17 '09 at 16:18
  • @sbi - I think you and I have different practical definitions of "work", but I see your point. @Nicholaz - Fair enough, I didn't realize that some implementations did this. – Bill Nov 17 '09 at 16:27