Author | Message | Time |
---|---|---|
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 |