I have a high memory requirement in my code and this statement is repeated a lot of times:
Node** x;
x = new Node*[11];
It fails at this allocation. I figured out this line by throwing output to the console!
I am building my code on Visual Studio. It works fine in Debug mode (both in VS2005 and VS2008)
However it throws the error in VS2005 Release mode.
A direct exe generated from
cl Program.cpp works if cl is from VS2010 but fails when it's from VS2005.
Any clues?
PS: Linux gives me a Bus Error(core dumped) for the same
Thanks
UPDATE:
And I guess, it can be due to 'unaligned' thing as I understand. I just made 11 to 12 (or any even number) and It works!!! I don't know why. It doesn't work with odd numbers!
Update 2 : http://www.devx.com/tips/Tip/13265 ?
I think you've done something somewhere else which corrupted the program heap: for example, writing past the end of an allocated chunk of memory, or writing to a chunk of memory after it's been freed.
I recommend that the easiest way to diagnose the problem would be to run the software using a kind of debugger that's intended to detect this kind of problem, for example valgrind.
I have a high memory requirement in my code
Are you actually running out of memory?
x = new Node*[11];
Are you deleting x like so:
delete [] x; // the correct way
or:
delete x; // incorrect
Or there could simply be something else corrupting the heap, though I would have expected that running in debug mode mode would make it more obvious, not less so. But with heap corruption there are rarely any guarantees that it'll do so in a nice, easy to debug way.
There is nothing wrong with this code.
Node **x;
x = new Node*[11];
You are allocating 11 pointers to class Node and storing it as a double-pointer in variable x. This is fine.
The fact that your program is crashing here is probably due to some memory error that is occurring elsewhere in your program. Perhaps you're writing past array bounds somewhere. If you load this array using a for loop, double-check your indexing.
If you have access to a memory profiler, I'd recommend using it. These bugs can be difficult to track down in large programs.
A valid C++98 implementation will throw an exception (std::bad_alloc) if allocation fails, not just crash. I'd agree with previous answers and suggest running your program in valgrind as this reeks of memory corruption. Valgrind should be available in your Linux distribution of choice.
Related
I have an std::string which appears to be getting corrupted somehow. Sometimes the string destructor will trigger an access violation, and sometimes printing it via std::cout will produce a crash.
If I pad the string in a struct as follows, the back_padding becomes slightly corrupted at a relatively consistant point in my code:
struct Test {
int front_padding[128] = {0};
std::string my_string;
int back_padding[128] = {0};
};
Is there a way to protect the front and back padding arrays so that writing to them will cause a exception or something? Or perhaps some tool which can be used to catch the culprit writing to this memory?
Platform: Windows x64 built with MSVC.
In general you have to solve problem of code sanitation, which is quite a broad topic. It sounds like you may have either out-of-bound write, or use of a dangling pointer or even a race condition in using a pointer, but in latter case bug's visibility is affected by obsevation, like the proverbial cat in quantum superposition state.
A dirty way to debug source of such rogue write is to create a data breakpont. It is especially effective if bug appears to be deterministic and isn't a "heisenbug". It is possible in MSVS during debug session. In gdb it is possible by using watch breakpoints.
You can point at the std::string storage or, in your experimental case, at the front padding array to in attempt to trigger breakpoint where a write operation occurs.
How can you catch memory corruption in C++?
The best way with a modern compiler is to compile with an address sanitizer. This inserts exactly the sort of guard areas you describe around automatic (stack) and dynamic (heap) allocations, and detects when they're trampled. It's built into Clang, GCC and MSVC.
If you don't have compiler support, or need to diagnose the problem in an existing binary without recompiling, you can use Valgrind.
The sanitized executable runs at full speed, although it's doing more work and deliberately has a less cache-friendly memory layout; expect it to be about 2x slower than an equivalent un-instrumented build.
Running under valgrind is much slower (expect 10x-30x for memcheck), but will catch more types of error, and is your only option if you can't recompile.
I've run into a strange problem. The Release version of my application seems to run fine, but recently when I switched to the Debug version, I got an access violation immediately on start-up. The access violation is occurring when a block of allocated memory is freed. All of this occurs in the constructor for a static variable.
I believe the problem doesn't occur in the Release version simply because I have defined NDEBUG there, which I believe disables assertions in the C runtime.
I've been able to narrow things down a bit. If I add the following code to the constructor before the usual calls, then I get the same error:
int *temp = new int[3];
delete[] temp;
This makes me think that something outside of this block of code is causing the problem, e.g., perhaps there is a problem with the way the C runtime is being linked. However, I'm at a loss to say what that problem might be, and after a day of poking at the problem I'm running out of ideas for where to poke next.
Any help would be greatly appreciated. I am using Visual Studio 2010 to compile the application and running Windows 7.
Thanks so much!
In Debug mode, additional checks are added; therefore it's not unusual for a program to run perfectly well in Release mode but to give an access violation in Debug mode. This doesn't mean that the Release version is OK; it only means that some error made when the Release version is running is not catched but is when running in Debug mode.
Debugging a corrupted memory problem in C/C++ is very hard because the error can be made by any other instruction affecting the memory. For example, if you have two arrays that follow one each other in the allocated memory and the first array is overrun, then it will corrupt the header put before the second array (each memory allocation is prefixed by an header; this header is used by the operators delete and delete[] when deallocating the memory). However, only when you will try to deallocate the second array that the access violation will occurs and this, even if it's with the first array that there is error in the code.
Of course, you can have other problems with the second array. For example, you can find that some or all of its values have been corrupted when trying to read from it. However, it's not always the case and in many occasions, it might behave perfectly well when reading or writing to or from it and you can have the exact same good behavior with the first array. It's not because you don't have any problem reading and writing to and from some array that you don't overstep its boundary and corrupting the memory above (or below) it. Sometimes, the problem will only show up when trying to deallocate the array and other times, the problem will show up otherwise; for example with the display of corrupted values.
I was able to produce a minimal example by cutting away essentially all of my application code. I reduced the InitInstance function to the following:
BOOL CTempApp::InitInstance()
{
int *temp = new int[3] ;
delete[] temp ;
return FALSE ;
}
Even with all of my application code stripped away, the problem persisted. After this, I created a new project in Visual Studio 2010, once again replaced InitInstance with my minimal version, and then added all of the Additional Dependencies from my original project in the linker options. With this configuration, the problem was reproduced.
Next, I started removing libraries from the list of dependencies. I managed to whittle the list down to a single third-party library which was causing the following linker warning despite being labeled as the debug version:
LINK : warning LNK4098: defaultlib 'msvcrtd.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
I think what's happening here is that the vendor has linked his debug library against the non-debug runtime. Presumably when my application calls delete[] there is some confusion as to what the parameters are for the call, and it is trying to delete a portion of memory I have not allocated.
I have tried adding the following to my Ignore Specific Default Libraries list:
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
as suggested here. However, the problem persists. I think the solution will be to contact the vendor and have them resolve the conflict.
Thanks again for your suggestions. I hope this answer will help someone else with debugging a similar problem.
I'm on amd64 architecture. The following code gets rejected by the g++ compiler at the "if" statement:
void * newmem=malloc(n);
if(newmem==0xefbeaddeefbeadde){
with the error message:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
I can't seem to find the magic incantation needed to get it going (and I don't want to use -fpermissive). Any help appreciated.
Background:
I'm hunting an ugly bug which crashes my program while requesting memory in some STL new operation (at least gdb told me that). Thinking it could be some memory overrun of one of the allocated memory chunks being, by bad luck, adjacent to memory used by the OS to manage memory lists of my program, I quickly overrode new(), new plus their delete counterparts with own routines that added memory fencing; and while the application still crashes (all fences intact (sigh)), gdb now told me this:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000604f5e in construct (__val=..., __p=0xefbeaddeefbeadde, this=<optimized out>)
at /usr/include/c++/4.6/ext/new_allocator.h:108
108 { ::new((void *)__p) _Tp(__val); }
I noted that the pointer __p has as value the pointer representation of the value I used for one of my memory fences (0xdeadbeef), hence my wish to catch this earlier in my new() to try and dump out some more complex values in my program.
Additional note: the function where it crashes runs flawlessly a couple of million times before it crashes (intermixed with dozens of other routines which all also run a couple of thousand to million times), using valgrind does not seem like an option atm because it takes 6hrs and 11 Gb before my program crashes.
One of them is an integer, and the other a pointer. Perhaps an ugly cast would do
if(newmem==(void*)0xefbeaddeefbeadde){
For your question: you have 2 options - cast the pointer to 64bit number or cast the number to void*
For the background: as this takes too long, it could be a memory leak. So, try valgrind - no need to wait for crash, just run your program through valgrind and use the appropriate options. valgrind could help you to catch undefined behavior, too.
Another thing - compile your program with -O0 optimization level and with max level of debug symbols - -ggdb3. Also, if your executable does not generate a core dump, when this error occurs, make it generate. Then leave it working, while you're trying different approaches to catch the error.
In case you don't succeed, you'll at least have a (hopefully) nice core dump, that you can examine with gdb your_exe the_core_dump. Then, watch the core frame by frame, watch the variables, etc.
If it's not a memory leak, it could be a memory corruption somewhere, undefined behavior or something like this. If a good core dump is generated, you'll probably catch the error. Or, at least, it could give you useful information about the case.
Another thing, that could be useful, if you generate a core dump (no matter if it's a good or a bad one) - the size of the dump. If it's too large (the definition of "large" this depends on your program), then you most probably have a memory leak (it could be some kind of cross-reference issue, if you use smart pointers and if so - valgrind will not catch it)
That probably won't work that way. Next time when your program runs, malloc may never return that value. There is something else you must do, rather than just checking on the return value of new!
I have a very simple C++ code here:
char *s = new char[100];
strcpy(s, "HELLO");
delete [] s;
int n = strlen(s);
If I run this code from Visual C++ 2008 by pressing F5 (Start Debugging,) this always result in crash (Access Violation.) However, starting this executable outside the IDE, or using the IDE's Ctrl+F5 (Start without Debugging) doesn't result in any crash. What could be the difference?
I also want to know if it's possible to stably reproduce the Access Violation crash caused from accessing deleted area? Is this kind of crash rare in real-life?
Accessing memory through a deleted pointer is undefined behavior. You can't expect any reliable/repeatable behavior.
Most likely it "works" in the one case because the string is still "sitting there" in the now available memory -= but you cannot rely on that. VS fills memory with debug values to help force crashes to help find these errors.
The difference is that a debugger, and debug libraries, and code built in "debug" mode, likes to break stuff that should break. Your code should break (because it accesses memory it no longer technically owns), so it breaks easier when compiled for debugging and run in the debugger.
In real life, you don't generally get such unsubtle notice. All that stuff that makes things break when they should in the debugger...that stuff's expensive. So it's not checked as strictly in release. You might be able 99 times out of 100 to get away with freeing some memory and accessing it right after, cause the runtime libs don't always hand the memory back to the OS right away. But that 100th time, either the memory's gone, or another thread owns it now and you're getting the length of a string that's no longer a string, but a 252462649-byte array of crap that runs headlong into unallocated (and thus non-existent, as far as you or the runtime should care) memory. And there's next to nothing to tell you what just happened.
So don't do that. Once you've deleted something, consider it dead and gone. Or you'll be wasting half your life tracking down heisenbugs.
Dereferencing a pointer after delete is undefined behavior - anything can happen, including but not limited to:
data corruption
access violation
no visible effects
exact results will depend on multiple factors most of which are out of your control. You'll be much better off not triggering undefined behavior in the first place.
Usually, there is no difference in allocated and freed memory from a process perspective. E.g the process only has one large memory map that grows on demand.
Access violation is caused by reading/writing memory that is not available, ususally not paged in to the process. Various run-time memory debugging utilities uses the paging mechanism to track invalid memory accesses without the severe run time penalty that software memory checking would have.
Anyway your example proves only that an error is sometimes detected when running the program in one environment, but not detected in another environment, but it is still an error and the behaviour of the code above is undefined.
The executable with debug symbols is able to detect some cases of access violations. The code to detect this is contained in the executable, but will not be triggered by default.
Here you'll find an explanation of how you can control behaviour outside of a debugger: http://msdn.microsoft.com/en-us/library/w500y392%28v=VS.80%29.aspx
I also want to know if it's possible
to stably reproduce the Access
Violation crash caused from accessing
deleted area?
Instead of plain delete you could consider using an inline function that also sets the value of the deleted pointer to 0/NULL. This will typically crash if you reference it. However, it won't complain if you delete it a second time.
Is this kind of crash rare in
real-life?
No, this kind of crash is probably behind the majority of the crashes you and I see in software.
I'm running my C++ program in gdb. I'm not real experienced with gdb, but I'm getting messages like:
warning: HEAP[test.exe]:
warning: Heap block at 064EA560 modified at 064EA569 past requested size of 1
How can I track down where this is happening at? Viewing the memory doesn't give me any clues.
Thanks!
So you're busting your heap. Here's a nice GDB tutorial to keep in mind.
My normal practice is to set a break in known good part of the code. Once it gets there step through until you error out. Normally you can determine the problem that way.
Because you're getting a heap error I'd assume it has to do with something you're putting on the heap so pay special attention to variables (I think you can use print in GDB to determine it's memory address and that may be able to sync you with where your erroring out). You should also remember that entering functions and returning from functions play with the heap so they may be where your problem lies (especially if you messed your heap before returning from a function).
You can probably use a feature called a "watch point". This is like a break point but the debugger stops when the memory is modified.
I gave a rough idea on how to use this in an answer to a different question.
If you can use other tools, I highly recommend trying out Valgrind. It is an instrumentation framework, that can run your code in a manner that allows it to, typically, stop at the exact instruction that causes the error. Heap errors are usually easy to find, this way.
One thing you can try, as this is the same sort of thing as the standard libc, with the MALLOC_CHECK_ envronment variable configured (man libc).
If you keep from exiting gdb (if your application quit's, just use "r" to re-run it), you can setup a memory breakpoint at that address, "hbreak 0x64EA569", also use "help hbreak" to configure condition's or other breakpoitn enable/disable options to prevent excessively entering that breakpoint....
You can just configure a log file, set log ... setup a stack trace on every break, "display/bt -4", then hit r, and just hold down the enter key and let it scroll by
"or use c ## to continue x times... etc..", eventually you will see that same assertion, then you will now have (due to the display/bt) a stacktrace which you can corolate to what code was modifying on that address...
I had similar problem when I was trying to realloc array of pointers to my structures, but instead I was reallocating as array of ints (because I got the code from tutorial and forgot to change it). The compiler wasnt correcting me because it cannot be checked whats in size argument.
My variable was:
itemsetList_t ** iteration_isets;
So in realloc instead of having:
iteration_isets = realloc(iteration_isets, sizeof(itemsetList_t *) * max_elem);
I had:
iteration_isets = realloc(iteration_isets, sizeof(int) * max_elem);
And this caused my heap problem.