By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,877 Members | 1,064 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,877 IT Pros & Developers. It's quick & easy.

delete POD array - on which platforms does it not work?

P: n/a
Hi all!

char* p = new char[n]; // POD!
....
delete[] p; // std compliant
delete p; // will work on VC8
free(p); // will also work on VC8
I am interested on which platforms/compilers the second two statements
would not work. (access violation or mem-leak).

thanks!
br,
Martin
Apr 2 '08 #1
Share this Question
Share on Google+
23 Replies


P: n/a
Martin T. wrote, On 2.4.2008 7:30:
Hi all!

char* p = new char[n]; // POD!
...
delete[] p; // std compliant
delete p; // will work on VC8
free(p); // will also work on VC8
I am interested on which platforms/compilers the second two statements
would not work. (access violation or mem-leak).
Why does it matter? It is wrong C++ even if it compiles and works.

--
VH
Apr 2 '08 #2

P: n/a
On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
delete p; // will work on VC8
free(p); // will also work on VC8
Are you sure these don't mess up anything in VC8?
Anyway this question is braindead. You use delete[]
for arrays and never free() with operator new.
Apr 2 '08 #3

P: n/a
Krice wrote:
On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
>delete p; // will work on VC8
free(p); // will also work on VC8

Are you sure these don't mess up anything in VC8?
Yes, 100% sure.
Anyway this question is braindead. You use delete[]
for arrays and never free() with operator new.
This is question is quite valid. Indeed it becomes more valid with
answers such as this. I could also rephrase it:
Is it (just) *really* evil, or does anyone know of a platform where it
will break for PODs?

br,
Martin
Apr 2 '08 #4

P: n/a
Martin T. wrote:
Krice wrote:
>On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
>>delete p; // will work on VC8
free(p); // will also work on VC8

Are you sure these don't mess up anything in VC8?

Yes, 100% sure.
Wrong. Mixing different kinds of allocator/deallocator functions will
not work on any platform in general case. That applies to VC8 as well.
The memory allocation functions hiding behind these new/delete
expressions can be overloaded completely independently, leading to
disastrous results in the above code samples.

Remember, new/delete, new[]/delete[] and malloc/free are three
alternative and completely independent memory allocation approaches,
which bear absolutely no relation to each other. For this reason, they
can't be mixed in the above manner.

--
Best regards,
Andrey Tarasevich
Apr 2 '08 #5

P: n/a
Martin T. wrote:
Krice wrote:
>On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
>>delete p; // will work on VC8
free(p); // will also work on VC8

Are you sure these don't mess up anything in VC8?

Yes, 100% sure.
>Anyway this question is braindead. You use delete[]
for arrays and never free() with operator new.

This is question is quite valid. Indeed it becomes more valid with
answers such as this. I could also rephrase it:
Is it (just) *really* evil,
There is nothing evil about it. It is just undefined behavior.
or does anyone know of a platform where it
will break for PODs?
It is undefined behavior on any platform. That makes it somewhat hard to
produce a test case.
Best

Kai-Uwe Bux
Apr 2 '08 #6

P: n/a
Martin T. wrote:
Krice wrote:
>On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
>>delete p; // will work on VC8
free(p); // will also work on VC8

Are you sure these don't mess up anything in VC8?

Yes, 100% sure.
How can you be so sure? Are you sure that they don't, for example,
leak memory? Did you use some kind of profiler to check this or something?
Apr 2 '08 #7

P: n/a
In article <fs**********@registered.motzarella.org>,
Martin T. <0x********@gmx.atwrote:
>Hi all!

char* p = new char[n]; // POD!
...
delete[] p; // std compliant
delete p; // will work on VC8
free(p); // will also work on VC8
I am interested on which platforms/compilers the second two statements
would not work. (access violation or mem-leak).
Philosophically, the question is somewhat interesting and as other
posters have already answer, this is undefined behavior.

On Linux using g++ 4:
#include <cstdlib>
int main()
{
char* p = new char[100]; // POD!
delete[] p; // std compliant
char *q = new char[100];
delete q; // will work on VC8
char *r = new char[100];
free(r); // will also work on VC8
return 0;
}

valgrind reports the following errors:
==17797== Mismatched free() / delete / delete []
==17797== at 0x4004E56: operator delete(void*)
(vg_replace_malloc.c:244)
==17797== by 0x8048552: main (newdelete.cpp:7)
==17797== Address 0x40290C0 is 0 bytes inside a block of size 100
alloc'd
==17797== at 0x400595C: operator new[](unsigned)
(vg_replace_malloc.c:195)
==17797== by 0x8048541: main (newdelete.cpp:6)
==17797==
==17797== Mismatched free() / delete / delete []
==17797== at 0x400513F: free (vg_replace_malloc.c:233)
==17797== by 0x8048570: main (newdelete.cpp:9)
==17797== Address 0x4029158 is 0 bytes inside a block of size 100
alloc'd
==17797== at 0x40595C: operator new[](unsigned)
(vg_replace_malloc.c:195)
==17797== by 0x804855F: main (newdelete.cpp:8)

I don't know if it would damage my heap per se but valgrind is
noticing a problem with the compiled code.

Practically however: I do not remember the last time I used new[]. I
honestly never use it. In the huge huge huge majority of cases,
"std::vector<int>(n)" will do better than "new int[n]".

I find "new" useful, albeit rarely, but "new[]", virtually never.

Yan
Apr 2 '08 #8

P: n/a
On 2 huhti, 10:02, "Martin T." <0xCDCDC...@gmx.atwrote:
Is it (just) *really* evil, or does anyone know of a platform
where it will break for PODs?
GCC and VC++ free edition (is that 2005?). There you go.
Apr 2 '08 #9

P: n/a
On 2 Apr, 10:47, Juha Nieminen <nos...@thanks.invalidwrote:
Martin T. wrote:
Krice wrote:
On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
delete p; * // will work on VC8
free(p); * *// will also work on VC8
Are you sure these don't mess up anything in VC8?
Yes, 100% sure.

* How can you be so sure? Are you sure that they don't, for example,
leak memory? Did you use some kind of profiler to check this or something?
The _CrtDumpMemoryLeaks() function can be used when running under the
debugger. I too tried this, and was unable to produce a memory leak on
VC8.

Without further evidence, I wouldn't go as far as saying that this is
100% safe on VC8, but it would seem that the most trivial cases are
handled gracefully.

DP
Apr 2 '08 #10

P: n/a
Andrey Tarasevich wrote:
Martin T. wrote:
>Krice wrote:
>>On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
delete p; // will work on VC8
free(p); // will also work on VC8

Are you sure these don't mess up anything in VC8?

Yes, 100% sure.

Wrong. Mixing different kinds of allocator/deallocator functions will
not work on any platform in general case. That applies to VC8 as well.
The memory allocation functions hiding behind these new/delete
expressions can be overloaded completely independently, leading to
disastrous results in the above code samples.
Of course if the memory allocation functions for the POD in question be
overloaded, then it would break with high probability.
For most projects I have worked with though, this can be ruled out. (I'm
sure there are some very valid examples where it's used.)

Make it 100% sure (for VC8) when new/delete are not overloaded for the POD.
Remember, new/delete, new[]/delete[] and malloc/free are three
alternative and completely independent memory allocation approaches,
which bear absolutely no relation to each other. For this reason, they
can't be mixed in the above manner.
As I see it, they are independent in the standard and it's undefined
behavior according to that.
However, my question was (and I'm sure there are): On which
platform/compiler *implementations* will code such as this break in
release code. (break = access violation or memory leak)

br,
Martin
Apr 2 '08 #11

P: n/a
Krice wrote:
On 2 huhti, 10:02, "Martin T." <0xCDCDC...@gmx.atwrote:
>Is it (just) *really* evil, or does anyone know of a platform
where it will break for PODs?

GCC and VC++ free edition (is that 2005?). There you go.
The current version of the VC++ free edition is 2008 (VC9 I believe) and
I have a hard time believing that it will break there. Care to explain
how it breaks there (in the absence of overloaded allocation)?

br,
Martin
Apr 2 '08 #12

P: n/a
Kai-Uwe Bux wrote:
Martin T. wrote:

....
>or does anyone know of a platform where it
will break for PODs?

It is undefined behavior on any platform. That makes it somewhat hard to
produce a test case.
Well, I am sure the standard says something about the outcome of a
delete[] for PODs ... ?
So, if the outcome of the free(new char[n]) is the same, one could say
it does not break in this specific implementation, right?

br,
Martin
Apr 2 '08 #13

P: n/a
Martin T. wrote:
>>
Wrong. Mixing different kinds of allocator/deallocator functions will
not work on any platform in general case. That applies to VC8 as well.
The memory allocation functions hiding behind these new/delete
expressions can be overloaded completely independently, leading to
disastrous results in the above code samples.
Of course if the memory allocation functions for the POD in question be
overloaded, then it would break with high probability.
...
Make it 100% sure (for VC8) when new/delete are not overloaded for
the POD.

Not necessarily "for the POD". The global memory allocation functions
can be overloaded. (You you can't overload memory allocation functions
specifically for 'char', which is what was used in your original example).

Note, that it is impossible to say whether the global functions are
overloaded by just looking at the type your are trying to work with.
For most projects I have worked with though, this can be ruled out. (I'm
sure there are some very valid examples where it's used.)
I don't understand "ruled out" here. You could say that for most
projects you have worked with the overloading didn't take place. Which
is mildly strange.

And, once again, "ruling it out" for the global overload requires the
inspection of the entire project.
>
>Remember, new/delete, new[]/delete[] and malloc/free are three
alternative and completely independent memory allocation approaches,
which bear absolutely no relation to each other. For this reason, they
can't be mixed in the above manner.

As I see it, they are independent in the standard and it's undefined
behavior according to that.
They are independent in practice as well. You just haven't seen them
overloaded for some reason.
However, my question was (and I'm sure there are): On which
platform/compiler *implementations* will code such as this break in
release code. (break = access violation or memory leak)
Not exactly. What you checked is on which platforms this will work with
that platform's default implementations of memory
allocation/deallocation functions.

I don't see how it can be even remotely useful.

--
Best regards,
Andrey Tarasevich
Apr 2 '08 #14

P: n/a
On Apr 2, 7:40*am, "Martin T." <0xCDCDC...@gmx.atwrote:
However, my question was (and I'm sure there are): On which
platform/compiler *implementations* will code such as this break in
release code. (break = access violation or memory leak)
How should we know and why do you expect us to test for you? God, I
hope you don't write production software for anyone.
Apr 2 '08 #15

P: n/a
Martin T. wrote:
>Are you sure these don't mess up anything in VC8?

Yes, 100% sure.
>Anyway this question is braindead. You use delete[]
for arrays and never free() with operator new.

This is question is quite valid. Indeed it becomes more valid with
answers such as this.
There are so many morons who are 100% sure that it's safe to pour
lighter fluid into a burning barbecue fire -- /although/ they've been
told otherwise. "Sissies", they say. They do it dozens of times, and
nothing bad happens. Then they'll do it once more and get a third-degree
burn, and some bystanders too.

I just don't get into the mindset of these people.
Apr 2 '08 #16

P: n/a
Martin T. wrote:
Kai-Uwe Bux wrote:
>Martin T. wrote:

....
>>or does anyone know of a platform where it
will break for PODs?

It is undefined behavior on any platform. That makes it somewhat
hard to produce a test case.

Well, I am sure the standard says something about the outcome of a
delete[] for PODs ... ?
So, if the outcome of the free(new char[n]) is the same, one could
say it does not break in this specific implementation, right?

But you would have to have some explicit guarantees from the
implementor. Like Kai-Uwe says, we can never test for undefined
behavior, because it doesn't have to be consistent.
Bo Persson
Apr 2 '08 #17

P: n/a
Triple-DES wrote:
On 2 Apr, 10:47, Juha Nieminen <nos...@thanks.invalidwrote:
>Martin T. wrote:
>>Krice wrote:
On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
delete p; // will work on VC8
free(p); // will also work on VC8
>>>Are you sure these don't mess up anything in VC8?
>>Yes, 100% sure.

How can you be so sure? Are you sure that they don't, for example,
leak memory? Did you use some kind of profiler to check this or
something?

The _CrtDumpMemoryLeaks() function can be used when running under
the debugger. I too tried this, and was unable to produce a memory
leak on VC8.
How many times did you run the test, and under what conditions?

What if it only fails first Wednesday after a full moon on leap years,
and only if an important customer is watching. That's usually when
Undefined Behavior goes bad.
>
Without further evidence, I wouldn't go as far as saying that this
is 100% safe on VC8, but it would seem that the most trivial cases
are handled gracefully.

It actually does work, but just by chance. Usually new[] has to store
a count, so the system can later know how many times delete[] has to
call the destructor for the objects in the array. As a space
optimization, the count is not stored for objects without a
destructor, so by pure chance a char[10] object has the same layout as
any other 10 byte memory block.

Do you want to rely on this??
Bo Persson
Apr 2 '08 #18

P: n/a
Martin T. wrote:
Hi all!

char* p = new char[n]; // POD!
...
delete[] p; // std compliant
delete p; // will work on VC8
free(p); // will also work on VC8
How do you konw it works?


Brian
Apr 2 '08 #19

P: n/a
Triple-DES wrote:
On 2 Apr, 10:47, Juha Nieminen <nos...@thanks.invalidwrote:
>Martin T. wrote:
Krice wrote:
On 2 huhti, 08:30, "Martin T." <0xCDCDC...@gmx.atwrote:
delete p; * // will work on VC8
free(p); * *// will also work on VC8
>Are you sure these don't mess up anything in VC8?
Yes, 100% sure.

* How can you be so sure? Are you sure that they don't, for example,
leak memory? Did you use some kind of profiler to check this or something?

The _CrtDumpMemoryLeaks() function can be used when running under the
debugger. I too tried this, and was unable to produce a memory leak on
VC8.

Without further evidence, I wouldn't go as far as saying that this is
100% safe on VC8, but it would seem that the most trivial cases are
handled gracefully.
This certainly seems slightly more comfortable than "100% sure". That
level of confidence always sets off warning flags "100%" of the time :)

To be honest I'm not convinced that even this claim stands up very well.
How does optimizing, debugging, ... etc other environment changes impact
this outcome? I'm not asking for anyone to actually test this. I'm
personally willing to take the standard at it's word and consider it
undefined. From the first time I heard about it I've been adverse to
doing anything that might cause demons to fly out of my nose. My
children have moved back in with me and I'm already pressed for space.

I can't actually imagine why this question would ever come up. I can't
see any benefit from skirting the rules. Am I missing some possible
valid reason to investigate this?
Apr 3 '08 #20

P: n/a
On 3 Apr, 04:53, stan <smo...@exis.netwrote:
Triple-DES wrote:
[snip]
Without further evidence, I wouldn't go as far as saying that this is
100% safe on VC8, but it would seem that the most trivial cases are
handled gracefully.

This certainly seems slightly more comfortable than "100% sure". That
level of confidence always sets off warning flags "100%" of the time :)
Yes, and I guess I should moderate myself even further. What I should
have written was something along the lines of: Under certain
conditions, it is possible to write code in such a way that mixing
new[] / delete will not leak memory using VC8.
To be honest I'm not convinced that even this claim stands up very well.
How does optimizing, debugging, ... etc other environment changes impact
this outcome? I'm not asking for anyone to actually test this. I'm
personally willing to take the standard at it's word and consider it
undefined. From the first time I heard about it I've been adverse to
doing anything that might cause demons to fly out of my nose. My
children have moved back in with me and I'm already pressed for space.

I can't actually imagine why this question would ever come up. I can't
see any benefit from skirting the rules. Am I missing some possible
valid reason to investigate this?
My own reason for investigating this was that I wanted to convince the
OP that it was unsafe. Unfortunately, I haven't had any luck so far :)

DP
Apr 3 '08 #21

P: n/a
On 2 huhti, 15:41, "Martin T." <0xCDCDC...@gmx.atwrote:
The current version of the VC++ free edition is 2008
I'm using older version.
Care to explain how it breaks there
Heap corruption.
Apr 3 '08 #22

P: n/a
Triple-DES wrote:
On 3 Apr, 04:53, stan <smo...@exis.netwrote:
>Triple-DES wrote:
[snip]
>>Without further evidence, I wouldn't go as far as saying that this is
100% safe on VC8, but it would seem that the most trivial cases are
handled gracefully.
This certainly seems slightly more comfortable than "100% sure". That
level of confidence always sets off warning flags "100%" of the time :)

Yes, and I guess I should moderate myself even further. What I should
have written was something along the lines of: Under certain
conditions, it is possible to write code in such a way that mixing
new[] / delete will not leak memory using VC8.
>To be honest I'm not convinced that even this claim stands up very well.
How does optimizing, debugging, ... etc other environment changes impact
this outcome? I'm not asking for anyone to actually test this. I'm
personally willing to take the standard at it's word and consider it
undefined. From the first time I heard about it I've been adverse to
doing anything that might cause demons to fly out of my nose. My
children have moved back in with me and I'm already pressed for space.

I can't actually imagine why this question would ever come up. I can't
see any benefit from skirting the rules. Am I missing some possible
valid reason to investigate this?

My own reason for investigating this was that I wanted to convince the
OP that it was unsafe. Unfortunately, I haven't had any luck so far :)
No convincing was needed, actually. :-)
I'm not going to do this, but having a clue as to *how* evil something
is can never hurt. Not to repeat it, but to know how urgent it is to fix
it should you encounter it.

thanks for your insights,
br,
Martin
Apr 3 '08 #23

P: n/a
"Martin T." <0x********@gmx.atwrote in news:fsvuau$vct$1
@registered.motzarella.org:
Have you ever compared the performance of std::vector<int>(n) vs. new
int[n] (in a release build, but without optimization?)
My results are somewhere factor 5 on VC8 (VS2005) in favor of new[].
I agree though - I do not use new[] except in the classes that hide it
from me.
Well, without optimization you don't get fast code, do you? As a side
note, I have sometimes needed to switch on debugging support for Release
builds, but I have never had a need to switch off optimization there. So
what is your (company's?) excuse for doing that?

Also note that beginning from VS2005 MS has had the checked iterators
idea which is on by default even in the Release builds. They claim the
cost is small, but it cannot be zero. So for fair comparisons you have to
switch this one off also be #define SECURE_SCL 0 in the appropriate place
of the code. Though this won't count for factor 5 you mentioned...
Also - technically the (2003) std does not guarantee that the memory of
std::vector is allocated contiguously, right?
De facto all std::vectors are continuous, now and in the future. There
are many more real problems to worry about than this one.

Regards
Paavo

Jun 27 '08 #24

This discussion thread is closed

Replies have been disabled for this discussion.