Question

I had a programming error like this in malloc's size:

buffer = (char *) malloc(cbHash + 1);
assert(buffer);

instead of:

buffer = (char *) malloc(cbHash * 2 + 1);
assert(buffer);

I was writing two times more in buffer but in debug mode it did worked fine but on release it did crash in assert, that's how I figured out my mistake. My question is: how does debug differ from release executable? and why I didn't get error in debug mode?

Was it helpful?

Solution

Because you were writing still in application's memory space. Also writing outside of allocated memory results in an Undefined Behaviour, not necessarily a crash. Writing outside of app's memory results in a crash, because system sees that application violates memory of other program and violation access error is issued. However if you stay within app's memory, system cannot tell anything, and programs enters the UB state.

That is a short basic explanation. There is a little bit more to it. If you are interested I suggest looking into address spaces and memory access rights.

Also debug mode often does not have any optimizations and contains debug symbols as opposed to release builds. They might contain symbols, but often don't.

The assert could fail only if malloc failed for some reason.

OTHER TIPS

There are three main ways MSVC debug and release differ

  • Release uses the optimizer and debug does not
  • Debug includes symbolic debugging information in object files and release does not
  • The run time libraries are different.

One way the runtime libraries are different is in how malloc is implemented. The debug malloc allocates extra memory on both sides of your object and sets the extra memory to a bit pattern. When you free the memory, if the extra bits have been changed then your program has a memory overwrite bug and it will tell you so.

The debug heap allocates more memory than requested, and pads the "NoMansLand"-region before and after the buffer with a special signature. This is done to detect buffer overflows. When the memory is freed, the debug build checks the signatures and prints an error if it has changed.

The memory block itself is also initialized with special values, for msvcpp 0xcccccccc. In the release build, the memory is left as-is, and may contain any values. This is to try to detect coding errors that fail to initialize the memory. Maybe this could be a reason the debug build runs, while the release build crashes: If 0x00000000 is bad for the program, it doesn't crash with the debug build, but may with the release build.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top