Archived

This topic is now archived and is closed to further replies.

Dark Rain

What could cause a "new" to fail?

Recommended Posts

I have a pretty strange bug, it only happens when I''m not in debug mode in VC++. By that I mean in a Debug build but I''m not running the debugger, that''s when the crash happen (and in release too I might add). When I run the debugger, my program runs fine. Fair enough, so I started narrowing it down with msgbox. I had first thought it was going over the bounds of an array and that it was the different memory layout that was causing it to not crash in debug more. It wasnt that, I finaly came to a "new" that was causing the error. I dont understand what could cause a new to fail, it''s not as if I didnt have enough memory. Here''s the new : unsigned char *NewData = new unsigned char[Original.m_sizeX * Original.m_sizeY * CHANNEL]; Looks pretty basic to me. Of course I checked the values in Original to see if they were garbage but they''re correct.

Share this post


Link to post
Share on other sites
Are any of the three values you are multiplying negative by any chance? What is the total number of bytes you are trying to allocate?

Share this post


Link to post
Share on other sites
On the precise case where it fails, I'm trying to allocate "32*22*4". Hardly something to make it crash.

EDIT : After a bit of poking around, when I change the conditions, it's another memory allocation that fails. I'm a bit puzzled. Something is really fishy here.

[edited by - Dark Rain on October 17, 2002 11:21:02 AM]

Share this post


Link to post
Share on other sites
Perhaps you can run your program outside the debugger, and attach once it crashes? Also, I''ve seen problems of this sort caused by bad goings on earlier in the program, such as writing outside the bounds of an array. Good luck!

Share this post


Link to post
Share on other sites
Yeah, I was thinking it might be that too, I''ve messed up somewhere before. How does one enter the debugger when he didnt start with it? Or did you mean something else by "attach".

Share this post


Link to post
Share on other sites
Assuming that you are getting some sort of dialog (Unhandled Exception, GPE, GPF, etc...) and your program is still running after it crashes, do the following:

1) Make sure you are running a Debug version of your program
2) Run it and make it crash, but leave any dialogs up
3) Run VC++
4) Go to ''Build | Start Debug | Attach to Process...''
5) Pick your .exe from the list
6) Go to ''Debug | Break'' to pause your application
7) Debug as usual (call stack, watch window, memory window, etc...)
8) Fix the bug!

Good luck, and be sure to let us know what the problem was.

Share this post


Link to post
Share on other sites
Maybe the assert(0) function would help too... I use that to run a debug build without starting the debugger, and jump in the code when something crashes...

As a sidenote, I invite you to have a look at MMGR on this site:
http://www.fluidstudios.com/publications.html

You know that everything you ''new'' must have its ''delete'' to avoid memory leaks? Well in a large proggy it gets tricky to make sure of that, MMGR is simple-as-heck to use (include the .h in the right place) and provides lots of memory-checking safety... Plus it even helped me find out some overbound/underbound errors with arrays.

(Though I''m trying to think up a way to redefine operator [] to -really- watch my arrays)

Share this post


Link to post
Share on other sites
Thanks for the link Spacecat but I already use _CrtMemState to check for memory leaks so I''m pretty safe on that side ^_^.

I''ll try it Glyph, I didnt know you could do that, it''ll be really useful, thanks.

Share this post


Link to post
Share on other sites
Mmmm problematic, I tried attaching to the proccess but it''s not in the list. I''m getting an "application error", it''s a memory could not be written one.

I also tried closing VC++ and running it from the .exe directly and then opening VC++ but it wont start till I closed the .exe that crashed. Odd

After a bit of research, I cant seem to attach to a process even when it''s not crashing ;(.

Share this post


Link to post
Share on other sites
There are some cases where a process won''t be listed by default (such as a service under NT/2K)... try checking off the ''Show System Processes'' checkbox in the ''Attach To Process'' dialog.

One other thing to try that has helped me in the past is to start the program in the debugger, then enable some Exception breaks by going to ''Debug | Exceptions'' and selecting ''Stop always'' for things like ''Access Violation'' and ''Microsoft C++ Exception''. Good luck!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Dark Rain
I have a pretty strange bug, it only happens when I''m not in debug mode in VC++. By that I mean in a Debug build but I''m not running the debugger, that''s when the crash happen (and in release too I might add). When I run the debugger, my program runs fine.

Fair enough, so I started narrowing it down with msgbox. I had first thought it was going over the bounds of an array and that it was the different memory layout that was causing it to not crash in debug more. It wasnt that, I finaly came to a "new" that was causing the error. I dont understand what could cause a new to fail, it''s not as if I didnt have enough memory. Here''s the new :

unsigned char *NewData = new unsigned char[Original.m_sizeX * Original.m_sizeY * CHANNEL];

Looks pretty basic to me. Of course I checked the values in Original to see if they were garbage but they''re correct.





There are very few cases where new will fail but based on the code sample you''ve given us I''d suspect that either Original.m_sizeX, Original.m_sizeY, or CHANNEL is equil to 0. And with a little math here we know anything you multiply by 0 is equil to zero. So your basically trying to do a unsigned char* ptr = new unsigned char[0]; And as far as C++ is concerned that''s not valid.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
In debug all your pointers are initialized to NULL by default. In release mode they are not. Though in this case it should not matter, you may wish to set your pointer to null before newing it just for saftey''s sake. This is the most common reason for debug to release problems.

Share this post


Link to post
Share on other sites
Well as I said earlier, I already checked all the values involved in the new to make sure they werent garbage ie : the value I wanted, not negative and not 0.

When Glyph mentionned 2k/NT, I realised that this machine was just installed at work and the service pack might not've been installed. It wasnt installed and after an install, it confirmed my suspicions that VC++ needed to be updated to attach in 2k. Also I dont have my bug anymore, which is kinda unnerving because it might just be because the memory layout is different and it was the only test case where I had the bug. Might've been a VC++ bug that was fixed in the service pack, it's hard to tell.

Well I suppose nothing was lost, thanks to Glyph I learnt something new about debugging and that's always good ^_^.

[edited by - Dark Rain on October 17, 2002 2:37:08 PM]

Share this post


Link to post
Share on other sites
I had a similar bug a few weeks ago. Turned out to be a wild pointer in a totally unrelated part of my code.

I figured the "new" command changed the structure of my memory which in turn caused the pointer to point to a protected area.



Share this post


Link to post
Share on other sites
There is nothing wrong with new unsigned char[0]. It will return a perfectly valid pointer to 0 elements and you must release it with delete [] just like you would any other array.

I would suspect that you have memory corruption somewhere in your app before the point where you''re seeing the crash and calling new at that time just happens to expose it. It might not happen when debugging within VC because NT gives you a different allocator (that does more checking) when an app is started in a debugger.

You might have some luck getting a debugger attached by starting your app, have a message box to pause it very early on, bring up the task manager (ctrl-shift-esc), select the processes tab, use View->Select Columns to display the pid, then running VC with msdev -p .

-Mike

Share this post


Link to post
Share on other sites
I''m pretty sure you can run the release .exe from the debugger. You can also make a third configuration (copy the Debug settings), and slowly change it to the Release settings. Depending on the type of error, this can help narrow down the problem. You can also copy the Release settings, and drop-down the optimization to see the effect it has.

When your debugging a release build, the IDE doesn''t always report the correct line. The problem may be in the code above the new, or perhaps just below it.

However, you are most likely trashing the heap with a buffer-over run. Find the last allocation that is executed prior to this one, and scrutinize that code for errors.

...
quote:
Original post by Anonymous Poster
In debug all your pointers are initialized to NULL by default. In release mode they are not. Though in this case it should not matter, you may wish to set your pointer to null before newing it just for saftey''s sake. This is the most common reason for debug to release problems.


Under MSVC 6 & 7, when running in debug mode, allocated memory is filled with 0xcc - it is purposedly /not/ nulled.

Also, the pointer is set to the return value of new, unless new throws. new does not throw (by default) on MSVC.

So in the event of an allocation failure on MSVC, new will return 0, and thus the pointer will be set to a known, if undesirable, state.


Also, new int[0] is allowed, and is not allowed to return 0 - malloc has the same requirements. You also need to free this pointer or you will leak. The system adds a few bytes to every allocation that it uses to keep track of the heap. Any reading or writting of such a pointer engenders ''undefined'' behavior (of the buffer over-run flavor).

A static/stack array of size 0, e.g. char crap[0], is not allowed, but dynamic allocations of size 0 are.


...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hi ..

youre problem is (like somebody else wrote before) not this specific new allocation.

assumed you testet your values correctly

to prove this just

isolate the "problem" part of your code and compile it seperate into a complete new programm.

if the new program causes no errors, put the part in a loop and let it run for a few minutes/hours/days .

regards..






Share this post


Link to post
Share on other sites