i am using VS08 to build/run the following c++ code:
#include <stdlib.h>
struct Header
{
int count;
}*lstHeader=NULL;
int main()
{
for(int i=0;i<10;i++)
{
lstHeader=(Header*)realloc(lstHeader,sizeof(Header)+i);
lstHeader[i].count=i;
}
return 1;
}
and after running i get the following VS exception:
Windows has triggered a breakpoint in MyProgram.exe.
This may be due to a corruption of the heap, which indicates a bug in
MyProgram.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while MyProgram.exe has focus.
The output window may have more diagnostic information.
i have tried to malloc lstHeader instead of assigning it to NULL, but the same VS exception occured and i can’t figure y.
You need to think of what happens when
igets to 1. Let’s assume a four-byte integer.At
i == 0, you allocate enough bytes for oneHeaderplus an extra zero bytes. Then you setHeader[0].countto 0. No problems there, you’ve only changed the four bytes you allocated.At
i == 1, you allocate enough bytes for oneHeaderplus an extra one byte (for a total of five bytes). Then you setHeader[1].countto 1. This changes bytes 4, 5, 6 and 7 (zero-based) of your memory block despite the fact you only have bytes 0 through 4 available to you. In other words, that operation required an extra four bytes rather than the one extra byte you asked for.Looking at it graphically:
As you can see, each iteration gives you an extra byte, but you need an extra four bytes. Now this actually may work for a while, since most
malloccalls give you a minimum resolution such as 16 bytes (ask for 1, 2, 3 or 16 and you get 16, ask for 20 or 30, you get 32). But it’s still undefined behaviour and you shouldn’t rely on it.And, in any case, you’ll eventually get to the point where that won’t help any more. That point is where the
sizeof*(i+1)that you need goes above a 16-byte threshold while thesizeof+ithat you asked for stays below it. Then you’ll write beyond your allocated memory (even with the padding) and you’ll hose the memory arena.What you should probably have is:
This will make sure you have enough space for the needed
Headerelements in your memory allocation. The reason it’si+1is because the initial allocation has to have one element even thoughiis zero.