Valhalla Legends Forums Archive | General Programming | Weird memory-associated error

AuthorMessageTime
tA-Kane
I seem to be having trouble with one of the most fundamental operators of C++: the new and delete operators. Hmmm...

[code] int i;
char *saved;
bool success;

// some initialization and sanity checks here
...

// msg->line is a char array
i = strlen(msg->line);
if (i <= 0)
saved = NULL;
else
{
saved = new char[i];
if (saved)
strcpy(saved, msg->line);
}

// middle code that modifies msg->line
...

// now check to see if i want to log the msg, if i do, then restore msg->line and send to logging function
if (!success)
{
if (!saved)
irc_dbg(__FILE__, __LINE__, "failure saving message, hopefully no changes were made");
else
strcpy(msg->line, saved);
irc_log(irc, msg);
if (saved)
delete[] saved;
}
[/code]Now, this code looks fine to me, but when I execute it, I get an error...
[quote]Debug Error!

Program C:\Program Files\SphtBotv3\SphtBotv3.exe

DAMAGE: after Normal block (#63) at 0x020D1C40.


(Press Retry to debug the application)[/quote]

I've traced it down to the delete[] call, but I don't think I'm understanding why that's failing...?

I've also tried removing the code between the allocation and the deallocation, thinking maybe I fucked up somewhere and was modifying saved, but no... even with no middle code, it still fails.

Could someone point me in the right direction, please?
February 7, 2005, 11:44 PM
tA-Kane
Aha, I've figured it out. I was forgetting to include room for the null terminator that strcpy() would create...  :\

Here's the corrected line, for anyone interested:
[code] saved = new char[i+1];[/code]
February 8, 2005, 12:55 AM
EpicOfTimeWasted
Another thing is that in your case, new will never return zero, it will throw bad_alloc.  So the if(saved) after the new isn't needed.
February 8, 2005, 1:35 AM
Eibro
Another thing is that delete and delete[] will take no action on a null pointer, so if ( saved ) delete[] saved; is not necessary.
February 8, 2005, 3:22 AM
Mephisto
[quote author=S-1-1-0 link=topic=10464.msg98752#msg98752 date=1107832976]
Another thing is that delete and delete[] will take no action on a null pointer, so if ( saved ) delete[] saved; is not necessary.
[/quote]

Why isn't it necessary?  He's checking to make sure that it's necessary to free the allocated memory that's remaining.

Also, isn't it common that delete will crash when operating on a pointer which points to nothing?  I've forgotten under which instances a call to free() or delete will cause the program execution to crash due to operating on an "invalid pointer."
February 8, 2005, 6:06 AM
K
[quote author=S-1-1-0 link=topic=10464.msg98752#msg98752 date=1107832976]
Another thing is that delete and delete[] will take no action on a null pointer, so if ( saved ) delete[] saved; is not necessary.
[/quote]

Although deleting a NULL pointer is guaranteed by the C++ standard to have no action, quite a few implementations of delete will zonk out if you try to delete a NULL pointer.
February 8, 2005, 6:16 AM
tA-Kane
Thx for the heads up people. Now I have to fix more.  ;)

As for checking if the pointer is NULL before attempting to free, I'd rather do that locally and be assured that delete isn't going to get screwy with me.

[quote author=EpicOfTimeWasted link=topic=10464.msg98734#msg98734 date=1107826536]in your case, new will never return zero, it will throw bad_alloc.[/quote]When will it return zero?
February 8, 2005, 3:57 PM
EpicOfTimeWasted
[quote author=tA-Kane link=topic=10464.msg98795#msg98795 date=1107878228]
[quote author=EpicOfTimeWasted link=topic=10464.msg98734#msg98734 date=1107826536]in your case, new will never return zero, it will throw bad_alloc.[/quote]When will it return zero?
[/quote]

You can tell new to not throw an exception and instead return zero.

[code]saved = new(nothrow) char[i + 1];
if(saved)
  strcpy(saved, msg->line);[/code]
February 8, 2005, 4:55 PM
Mephisto
[quote author=tA-Kane link=topic=10464.msg98795#msg98795 date=1107878228]
Thx for the heads up people. Now I have to fix more.  ;)

As for checking if the pointer is NULL before attempting to free, I'd rather do that locally and be assured that delete isn't going to get screwy with me.

[quote author=EpicOfTimeWasted link=topic=10464.msg98734#msg98734 date=1107826536]in your case, new will never return zero, it will throw bad_alloc.[/quote]When will it return zero?
[/quote]

Keep in mind that your check could evaluate to true if a pointer isn't NULL but has not been dynamically allocated and thus would result in a crash if you attempted to delete it.  But I doubt that would happen in any event.
February 8, 2005, 7:56 PM
Eibro
[quote author=tA-Kane link=topic=10464.msg98795#msg98795 date=1107878228]
Thx for the heads up people. Now I have to fix more.  ;)

As for checking if the pointer is NULL before attempting to free, I'd rather do that locally and be assured that delete isn't going to get screwy with me.

[quote author=EpicOfTimeWasted link=topic=10464.msg98734#msg98734 date=1107826536]in your case, new will never return zero, it will throw bad_alloc.[/quote]When will it return zero?
[/quote]It won't. It's guaranteed to do nothing with a NULL pointer.
February 8, 2005, 8:16 PM
tA-Kane
I found an interesting article related to a bug in the version of VS I am using (VS6):

http://msdn.microsoft.com/msdnmag/issues/03/09/LegacySTLFix/default.aspx


Hmmm... maybe I should ... "find" ... VS.NET, and use that...  :\
February 8, 2005, 8:35 PM
Kp
Or switch to MinGW's g++. :)
February 8, 2005, 9:54 PM

Search