delete causes crash with character arrays

A

Alex Vinokur

GNU g++ 3.3.3, Cygwin


// Stuff

static char* mbuffer = NULL;

// Stuff

void doit()
{
// Stuff
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

// Stuff

assert (mbuffer != NULL);
delete[] mbuffer; // Sometimes crashed here (not always).
mbuffer = NULL;

// Stuff

}

How can one detect what causes the crash?
 
M

Matthias

Alex said:
// Stuff
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

What is nothrow?
delete[] mbuffer; // Sometimes crashed here (not always).
mbuffer = NULL;

It looks like you're deleting memory allocated by placement new with a
"normal" delete. This is illegal IIRC. You will have to define your own
"placement delete" function.
 
A

Alex Vinokur

Matthias said:
Alex said:
// Stuff -------------------------------------------------
mbuffer = new (nothrow) char [1001]

// The program crashes at 'delete[] mbuffer' with the line below (instead of line above) too
mbuffer = new char [1001];
-------------------------------------------------
assert (mbuffer != NULL);

What is nothrow?
delete[] mbuffer; // Sometimes crashed here (not always).
mbuffer = NULL;

It looks like you're deleting memory allocated by placement new with a
"normal" delete. This is illegal IIRC. You will have to define your own
"placement delete" function.
 
I

Ivan Vecerina

Alex Vinokur said:
GNU g++ 3.3.3, Cygwin ....
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

// Stuff
Methinks this Stuff is what actually causes the crash.
assert (mbuffer != NULL);
delete[] mbuffer; // Sometimes crashed here (not always).

Except if you somehow change the value of mbuffer,
some buffer overflow is most likely corrupting the heap
and causing the crash.

Most platforms have tools that can help you detect heap
corruption, or a debugging implementation of heap allocation
functions.
A poor man's first try could also be to do:
mbuffer = 1+new (nothrow) char [1001+2];
mbuffer[-1] = 0x77; //magic number to detect overwrite
mbuffer[1001] = 0x77;

//Stuff... <-- look for change of mbuffer[-1 or 1001]
// e.g. by inserting assertions..

delete[] (mbuffer-1);
 
M

Matthias

Alex said:
Matthias said:
Alex said:
// Stuff
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

What is nothrow?


<QUOTE from http://groups-beta.google.com/group/comp.lang.c++/msg/d6565d1c77795e52 >

If you want 'new' to return NULL instead of throwing an exception, use

int* p = new (nothrow) int[array_size];

</QUOTE>

[snip]

So your call to new is not a call to placement new, but to the normal
new with the option "don't throw bad_alloc exception" set?
 
A

Alex Vinokur

Ivan Vecerina said:
Alex Vinokur said:
GNU g++ 3.3.3, Cygwin ...
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

// Stuff
Methinks this Stuff is what actually causes the crash.
assert (mbuffer != NULL);
delete[] mbuffer; // Sometimes crashed here (not always).

Except if you somehow change the value of mbuffer,
some buffer overflow is most likely corrupting the heap
and causing the crash.

Most platforms have tools that can help you detect heap
corruption, or a debugging implementation of heap allocation
functions.
A poor man's first try could also be to do:
mbuffer = 1+new (nothrow) char [1001+2];
mbuffer[-1] = 0x77; //magic number to detect overwrite
mbuffer[1001] = 0x77;

//Stuff... <-- look for change of mbuffer[-1 or 1001]
// e.g. by inserting assertions..

delete[] (mbuffer-1);

Ivan,
I started to apply your method and while analyzing the code I found out the cause of the problem.
Of course, it was trampling memory.

infile.read (mbuffer, infile_size); // infile_size was greater than mbuffer size.

Thank you very much.
 
A

Alex Vinokur

Matthias said:
Alex said:
Matthias said:
Alex Vinokur wrote:

// Stuff
mbuffer = new (nothrow) char [1001];
assert (mbuffer != NULL);

What is nothrow?


<QUOTE from http://groups-beta.google.com/group/comp.lang.c++/msg/d6565d1c77795e52 >

If you want 'new' to return NULL instead of throwing an exception, use

int* p = new (nothrow) int[array_size];

</QUOTE>

[snip]

So your call to new is not a call to placement new, but to the normal
new with the option "don't throw bad_alloc exception" set?

[snip]

Yes. It is not a call to placement new, it is the normal new with the option that returns NULL if failed.
 
R

Ron Natalie

Matthias said:
It looks like you're deleting memory allocated by placement new with a
"normal" delete. This is illegal IIRC. You will have to define your own
"placement delete" function.

Defining a placement delete function won't help (if you mean defining
a deallocation function: operator delete). The placement delete deallocator
is only called if an exception happens during placement construction.

You need to do an explicit destructor call (if necessary for your type) and
then call the whatever deallocation is appropriate.
 
M

Matthias

Ron said:
You need to do an explicit destructor call (if necessary for your type) and
then call the whatever deallocation is appropriate.

Does that mean, placement new doesn't allocate memory in the first
place? And what would be a proper deallocation?
 
K

Karl Heinz Buchegger

Matthias said:
Does that mean, placement new doesn't allocate memory in the first
place?

Exactly that
And what would be a proper deallocation?

Whatever is the opposite of the allocation strategy you used
for providing the memory.

The whole point of placement new is that 'new' no longer cares
to reserve some memory, but it is the job of the programmer
to allocate (or don't allocate at all) it. 'placement new' simply
takes the raw memory you give to it and turn it into an object
(by calling a constructor). Everything else is the responsibility
of the programmer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top