3

Possible Duplicate:
( POD )freeing memory : is delete[] equal to delete ?

char* pChar = new char[10];

delete pChar; // this should not work but it has same effect as 
              // delete[], WHY?
              // I know this is illegal, but why does it work?
Community
  • 1
  • 1
Ramadheer Singh
  • 4,124
  • 4
  • 32
  • 44
  • 2
    Questions like this remind me that C++ is the language that gives you the power of assembler language along with the ease of use of assembler language :-) – Vivian River Jun 29 '10 at 20:21
  • 9
    http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13 – James Jun 29 '10 at 20:22
  • @James Roth: Exactly. I was about to link that myself. – Fred Larson Jun 29 '10 at 20:24
  • @Rising Star: Nobody should be using delete explicitly anyway. Have you checked out std::unique_ptr? Will automatically use delete, delete[], or a custom deletion functor. – Puppy Jun 29 '10 at 20:28
  • @james @Larson, but how does this work (let's say for one implementation where it works one time), how does it know about array size at runtime ? (is it stored somewhere?) – Ramadheer Singh Jun 29 '10 at 20:28
  • 2
    That's one of the things I hate about old-fashioned arrays. If I use vectors, I get to ignore all of this `delete` vs. `delete[]` stuff. – David Thornley Jun 29 '10 at 20:28
  • 1
    @Gollum: Read that FAQ link, and continue reading the next section (16.14). That explains how it works. Short answer: magic. 8v) – Fred Larson Jun 29 '10 at 20:29
  • 2
    @sbi: Awesome answer to that question you suggested as a duplicate. @Gollum, I suggest you read that one before you get pregnant. ;v) – Fred Larson Jun 29 '10 at 20:43
  • When you say "it works", how do you know the delete did the right thing? Just because it didn't crash? – James Jun 29 '10 at 21:53
  • @James Roth @Fred @sbi, I put '\2'(smiley) character in every element. then did **delete pChar** and **delete[] pChar**, both the times it cleared the memory. that is why I was asking how did it know about dynamic allocation size. and specifically in case of **delete**, cos even if there is size stored somewhere, that guy would never go look for it. – Ramadheer Singh Jun 29 '10 at 22:44

5 Answers5

12

It may appear to have the same effect, but it does not. If your array type was an abstract data type (i.e. a class) then the destructors on the last nine elements would not have been called.

Amardeep AC9MF
  • 18,464
  • 5
  • 40
  • 50
  • yes, I tried that, it only works with primitive types. – Ramadheer Singh Jun 29 '10 at 20:23
  • 1
    Also, if the type of the array was of a non POD that redefined delete and delete[], the first one would be called instead of the second one, which may lead to even more surprising results. The same holds if the global delete and delete[] were redefined. – Matteo Italia Jun 29 '10 at 20:27
  • Or if the compiler itself handled single allocations and array allocations differently, as it's allowed to do. Then it wouldn't "work" even with primitive types. Undefined behaviour is undefined. – Mike Seymour Jun 29 '10 at 21:10
8

Because you got lucky. This is undefined behavior. One possibility for undefined behavior is that nothing bad seems to happen, even if something bad really did happen. You might not find out until later.

You can't count on being safe with primitive types. Read this (also linked by James Roth in a comment): https://isocpp.org/wiki/faq/freestore-mgmt#delete-array-built-ins

Fred Larson
  • 60,987
  • 18
  • 112
  • 174
5

It doesn't work. It simply appears to work. The code that exhibits undefined behavior might appear to be "working" at the first sight, just like a program ridden with bugs might appear to "work fine" on a poorly selected test suite.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

It's undefined behavior. And since "it works this time" falls into the category of "undefined", it can work on some platform, on some compiler. Still, it shouldn't be done. Have you tried deallocing an array of objects with destructors like that, and seeing if the destructors get called?

EDIT : According to your comments, you did...

fingerprint211b
  • 1,176
  • 12
  • 24
0

In most versions of Microsoft Visual Studio this actually works correctly. However, there's no reason why this should be so, it's totally upto your platform.

The idea behind delete[] is that this is a special case in which size is not known at compile time, which the allocation framework might want to handle differently (and optimize the delete case).

Strictly speaking, delete pointerToBaseClass also doesn't have size known at compile time, but this is solved by virtual table, and compiler knows that the class is polymorphic at compile time.

If you mishandle delete[], it may also have problems with tools replacing the allocator (debuggers, boundscheckers of all kinds, etcetc) and custom allocators your users may use.

Pavel Radzivilovsky
  • 18,794
  • 5
  • 57
  • 67