After reading the question asked in this thread, I started wondering "Why not allocate the whole 2D array, including the pointers necessary to navigate the 2D array, at once?" My purpose was to basically create a 2D array that can be created with one call to new and deleted with one call to delete.
Code:
void** Make2DArray(int size, int xMax, int yMax)
{
void** buffer = (void**)new char[size*xMax*yMax+sizeof(void*)*xMax];
memset((void*)buffer, 0, size*xMax*yMax+sizeof(void*)*xMax);
for(int i = 0; i < xMax; i++)
buffer[i] = &((char*)buffer)[sizeof(void*)*xMax+size*yMax*i];
return buffer;
}
I started with the creation logic. I needed a buffer with enough space for all of the requested objects AND all of the x-axis pointers. As a diagnostic aid, I went ahead and zeroed out the contents of the buffer. I then needed to wire up x-axis pointers to point at the necessary blocks of memory.
Code:
void Delete2DArray(void** array)
{
delete[] (char*)array;
}
Because the entire array was created with a single call to new, I should be able to delete it all with a single call to delete. Because the buffer began life as a char array, I figured I should probably cast it back to a char pointer when deleting.
Code:
int main()
{
const int X_MAX = 20;
const int Y_MAX = 10;
int** bigArray = (int**)Make2DArray(sizeof(int),X_MAX,Y_MAX );
for(int x = 0; x < X_MAX; x++)
for(int y = 0; y < Y_MAX ; y++)
bigArray[x][y] = 10;
Delete2DArray((void**)bigArray);
return 0;
}
Here's the driver for testing out this memory-thrasher. It blows up while deleting. I'm not exactly sure why. I get the message:
"Windows has triggered a breakpoint in test.exe.
This may be due to a corruption of the heap, and indicates a bug in test.exe or any of the DLLs it has loaded."
I noticed that if I commented out the assignments to bigArray, then the delete worked. I tried tracing through the calls, and it finally blows away on a call to HeapValidate in _CrtIsValidHeapPointer. However, I still don't know why. What rules am I unknowingly breaking?
[EDIT] I forgot to mention that I'm working with VS 2005, in case that makes any difference.
[EDIT2] Added the fix pointed out by ZuK.