new and delete, please help

S

Spikinsson

I create a new char[] and when I attempt to delete it, the debug gives this error (during
runtime):

Debug Error!

Program: xxx

DAMAGE: after Normal block (#58) at 0x00C315A0.


I get this error everywhere I use delete []. When I remove all delete []'s from my code I
don't get the errors (nor does the program sometimes crash in release version
compilation), but I can't do that can I (memory leaks).

This is a part of my code:

** BEGIN **

int a = 0;
char *name = NULL;
a = GetWindowTextLength(GetDlgItem:):hwnd, IDC_NAME)) + 1;
if (!(name = new char[a]))
{
MessageBox:):hwnd,"Not enough memory to allocate the
value!",NULL,MB_OK|MB_ICONERROR);
return;
}
GetDlgItemText:):hwnd, IDC_NAME, name, a);
// THIS GIVES THE ERROR:
delete [] name;

** END **

When I check the name value, it does give the expected value!

I use MSVC++ 6.0 by the way.

I am pretty new at programming C++ and any help is very much appreciated, I really can't
figure out this one...
 
R

Ron Natalie

if (!(name = new char[a]))

This can only be zero on broken compilers like VC++ 6.
GetDlgItemText:):hwnd, IDC_NAME, name, a);

Hopefully, this writes no more than "a" chars to name.

The usual reasons delete blows up is because:

1. Overflow the allocation.
2. Delete something not alloc'd by new
3. Delete something twice.

It's not necessarily the thing that you are deleting that is the problem.
Sometimes it's some other allocation that was messed up.
 
S

Spikinsson

Ron Natalie said:
Spikinsson said:
if (!(name = new char[a]))

This can only be zero on broken compilers like VC++ 6.
Thanks for your quick response, I don't quite understand what you're saying here
actually...
Hopefully, this writes no more than "a" chars to name.
The definition GetDlgItemText says that the maximum characters written is a.
The usual reasons delete blows up is because:

1. Overflow the allocation.
I don't know what this is...
2. Delete something not alloc'd by new
As the code shows it is alloc'd by new.
3. Delete something twice.
Quite certain that this is not the case

It's not necessarily the thing that you are deleting that is the problem.
Sometimes it's some other allocation that was messed up.
If I surround the delete [] with 2 message boxes, I get the first message box, then the
error, than the second message box, so I figure that should be the erro...
 
R

Ron Natalie

Spikinsson said:
Ron Natalie said:
Spikinsson said:
if (!(name = new char[a]))

This can only be zero on broken compilers like VC++ 6.
Thanks for your quick response, I don't quite understand what you're saying here
actually...

Standard C++ will either return the successful allocation or throw a bad_alloc exception.
It will NEVER return null in the case above.
I don't know what this is...

Write outside the characters returned (usually off the end, but off the beginning is sure to cause a crash).
It's not necessarily the thing that you are deleting that is the problem.
Sometimes it's some other allocation that was messed up.
If I surround the delete [] with 2 message boxes, I get the first message box, then the
error, than the second message box, so I figure that should be the erro...
Not necessarily. Consider the following:

char* a = new char[10];
char* b = new char[10];
memset(b, 0, 100); // overlow the allocation of b.

MESSAGE_BOX
delete [] a; // BOOM!
MESSAGE_BOX

It's quite possible that some errant memory write or other abuse of new/delete has occurred.
It's just the first use of new/delete AFTER that error has occured that is hanging you.

Why not provide a complete minimal program that demonstrates your problem. The other
option is to look at what your compiler provides to help diagnose there. VC++ in debug
mode does have some stuff (look up mallocdbg or dbgmalloc, I don't remember) in the docs.
 
S

Spikinsson

Ron Natalie said:
Ron Natalie said:
if (!(name = new char[a]))

This can only be zero on broken compilers like VC++ 6.
Thanks for your quick response, I don't quite understand what you're saying here
actually...

Standard C++ will either return the successful allocation or throw a bad_alloc exception.
It will NEVER return null in the case above.
I don't know what this is...

Write outside the characters returned (usually off the end, but off the beginning is sure to cause a crash).
It's not necessarily the thing that you are deleting that is the problem.
Sometimes it's some other allocation that was messed up.
If I surround the delete [] with 2 message boxes, I get the first message box, then the
error, than the second message box, so I figure that should be the erro...
Not necessarily. Consider the following:

char* a = new char[10];
char* b = new char[10];
memset(b, 0, 100); // overlow the allocation of b.

MESSAGE_BOX
delete [] a; // BOOM!
MESSAGE_BOX

It's quite possible that some errant memory write or other abuse of new/delete has occurred.
It's just the first use of new/delete AFTER that error has occured that is hanging you.

Why not provide a complete minimal program that demonstrates your problem. The other
option is to look at what your compiler provides to help diagnose there. VC++ in debug
mode does have some stuff (look up mallocdbg or dbgmalloc, I don't remember) in the docs.

Thanks very much for your help, but I don't have the smallest clue how to successfully
debug, and the program is quite big at the moment so I can't really send that. Thanks
anyway and I'll try to look up some debug info...
 
S

Spikinsson

Write outside the characters returned (usually off the end, but off the beginning is
sure to cause a crash).
It's not necessarily the thing that you are deleting that is the problem.
Sometimes it's some other allocation that was messed up.
If I surround the delete [] with 2 message boxes, I get the first message box, then the
error, than the second message box, so I figure that should be the erro...
Not necessarily. Consider the following:

char* a = new char[10];
char* b = new char[10];
memset(b, 0, 100); // overlow the allocation of b.

MESSAGE_BOX
delete [] a; // BOOM!
MESSAGE_BOX

It's quite possible that some errant memory write or other abuse of new/delete has occurred.
It's just the first use of new/delete AFTER that error has occured that is hanging you.

Why not provide a complete minimal program that demonstrates your problem. The other
option is to look at what your compiler provides to help diagnose there. VC++ in debug
mode does have some stuff (look up mallocdbg or dbgmalloc, I don't remember) in the
docs.

Ok, but I don't quite know how to do this, I will look into it and repost, also, in debug
I get errors, and not in the release version, why? Are these errors even important, are it
those errors which only are showed in debug that cause the release version to sometimes
crash?
 
K

Karl Heinz Buchegger

Spikinsson said:
When I check the name value, it does give the expected value!

Looks like a bug in either MFC or Windows.

Have you tried to allocate one more character then GetWindowTextLength
tells you in order to account for a terminating '\0' character? I could
imagine that the situation is analogous to strlen. You need to allocate
one character more then strlen tells you, because strlen returns the number
of charcaters in a string, *not counting the terminating '\0'*

len = strlen( some_text );
name = new char [ len + 1 ];
strcpy( name, some_text );

Same here:

len = GetWindowTextLength( ... );
name = new char [ len + 1 ];
GetDlgItemText( ... );


By the way, have you checked what GetWindowTextLength returns
and compared that to your expectations for a known text?. Could
be your first encounter with a debugger to figure out that one.
 
M

Michiel Salters

Spikinsson said:
I create a new char[] and when I attempt to delete it, the debug gives
this error (during runtime):

Debug Error!

Program: xxx

DAMAGE: after Normal block (#58) at 0x00C315A0.


I get this error everywhere I use delete []. When I remove all delete []'s
from my code I don't get the errors (nor does the program sometimes
crash in release version compilation), but I can't do that can I
(memory leaks).

Let me explain what happens here.
When you do the new[] in debug mode, the compiler tacks on a few extra
bytes without telling you. In these bytes a special pattern is written.
You should not write more bytes than you asked for, so the pattern
should remain untouched.

Once you call delete[], the runtime checks if the pattern is still
in place. If it's damaged, you wrote too many bytes. This gives the
error above.

Remove the delete[]s and the runtime won't do the check. This is of
course a memory leak, and you still haven't solved the overwrite bug.

What you need to do is checking if you have allocated enough bytes.
Since you're dealing with char[]s, it might very well be a case of
not counting a \0. There are lots of other possible bugs, so check
all writes to the array.

The real solution would be to use a string or container of chars,
though. new[] char is a primitive.

Regards,
 
S

Spikinsson

Karl Heinz Buchegger said:
Have you tried to allocate one more character then GetWindowTextLength
tells you in order to account for a terminating '\0' character? I could
imagine that the situation is analogous to strlen. You need to allocate
one character more then strlen tells you, because strlen returns the number
of charcaters in a string, *not counting the terminating '\0'*

Thank you so much, that seems to have solved the problem! I'm really greatful for this,
now I created a function myself so I can edit it if I encounter more such problems.

char* new_array_pointer(int size)
{
return (char *)malloc(size+1);
}

void delete_array_pointer(char* a)
{
if (a != NULL)
free(a);
}

I don't use new now, but I think this is practically the same...
When I added the +1 to size everything was fixed! Thanks man!
 
J

John Harrison

Spikinsson said:
Thank you so much, that seems to have solved the problem! I'm really greatful for this,
now I created a function myself so I can edit it if I encounter more such problems.

char* new_array_pointer(int size)
{
return (char *)malloc(size+1);
}

void delete_array_pointer(char* a)
{
if (a != NULL)
free(a);
}

I don't use new now, but I think this is practically the same...
When I added the +1 to size everything was fixed! Thanks man!

Maybe I'm missing something but you did post this code

a = GetWindowTextLength(GetDlgItem:):hwnd, IDC_NAME)) + 1;
if (!(name = new char[a]))

According to that code you were adding one to GetWindowTextLength.

john
 
S

Spikinsson

Maybe I'm missing something but you did post this code

a = GetWindowTextLength(GetDlgItem:):hwnd, IDC_NAME)) + 1;
if (!(name = new char[a]))

According to that code you were adding one to GetWindowTextLength.

john

Yes, but also one was added to the maximum, as I use a there also:

GetDlgItemText:):hwnd, IDC_NAME, name, a);
 
K

Karl Heinz Buchegger

John said:
Maybe I'm missing something but you did post this code

a = GetWindowTextLength(GetDlgItem:):hwnd, IDC_NAME)) + 1;
if (!(name = new char[a]))

According to that code you were adding one to GetWindowTextLength.

That's why I think it really is a bug in Windows (or MFC).
It seems that the GetText function takes the buffer size
+ 1 extra character for the '\0'.

Haven't tested it though, just speculating.
 

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,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top