views:

269

answers:

7

So I have a function that creates a dynamic array, I then delete the array before I leave the function (as I thought I am supposed to), however I am getting a 'Heap Corruption Detected' warning in VS2008. If I remove the line that deallocates the memory everything works fine:

void myFunc()
{
    char* c = new char[length];
    memset(c, 0, length);

    //.. do somsething with array

    delete[] c; //this line throws an error??
}

Thanks for any advice

+11  A: 

Most likely you are doing something else bad (like under/overflowing your buffer) and corrupting the heap at that point, but it isn't detected until you call delete[] and try to interpret the now corrupted heap structures.

Post the 'do something' section if you need more assistance.

Nick Meyer
+7  A: 

I think you have a problem with your //.. do something with array code (or even some other code) since the rest of what you have is okay.

Often, memory arena corruption is only detected when freeing the memory which is probably why removing the line seems to fix it.

But rest assured, the arena is still corrupted whether or not you're detecting it. You need to fix it.


One way this might happen is if your memory allocation routines actually allocate extra bits before and possibly after what you're given. For example, if you ask for 1024 bytes, what might actually be allocated from the heap is a 1040-byte block of which you're given the address of the 16th byte. This gives the arena manager 16 bytes at the start to store housekeeping information (including a sentinal value at the very start of it).

Then, when the block is deleted, the arena manager knows that its housekeeping is in the 16 bytes before the address you're trying to free and can check the sentinal value (or all the sentinals in the arena or just the ones on either side of the one you're freeing - this is all implementation detail) to make sure they're unchanged. If they have been changed, that's detected as corruption.

As I said earlier, the corruption couuld be caused by your //.. do something with array code or it could be somewhere totally different - all that matters is that the arena is being trashed.

paxdiablo
A: 

This warning means you probably wrote to memory you don't own, perhaps by overrunning a buffer, freeing memory more than once, or forgetting to initialize a pointer before using it.

Good luck

Drewen
+1  A: 

Every time you allocate memory using new, you will need to free that memory using a matching delete. The code you quote should work.

C++ memory manager implementations typically interleave their control data structures with areas of memory you allocate. C++ does not bounds-check arrays for you. If your code writes data off the end or before the start of an array, this will corrupt the heap. It is very likely that this is what is happening here. Carefully examine the code that performs work on the array.

moonshadow
+3  A: 

You're probably underflowing the buffer, actually - the VC heap (and most heap implementations) keep book-keeping information immediately before the allocation they hand out. It includes some data validation (sentinel bytes, etc), which is it doesn't pass, this error is thrown.

Terry Mahaffey
+1  A: 

First, to answer the title, no dynamically allocated memory (with new, malloc, etc) is not freed when function exits. You are responsible for freeing it.

Second, just an advice that might help you debug your problem.

One great option is to use a free tool from Microsoft, called Application Verifier. It's a great tool to have in your toolbox, it's really great at helping you finding bugs in your applications.

Another option, not involving use of other tools would be, instead of your allocated array, you could try using std::vector, it might help detecting your heap corruption in debug mode. It has a huge amount of various checks in debug mode, which would likely cause it to break into debugger at the right time. Here's what you could try:

{
    const size_t size_of_array = 64;
    // use constructor with size and value
    // do _not_ use memset on this object
    std::vector<char> your_array(size_of_array, 0);

    // do something here with it e.g.:
    snprintf(&your_array[0], your_array.size(), "hello");

    // do whatever you do with your array
    // use debug build and run it under debugger,
    // likely you will spot your problem pretty soon

    // no need to delete anything here
}
Dmitry
A: 

delete does not throw. This is guaranteed. If you are allocating for some "length", and if you are using the entire char array without having '/0' at the end, then you would get this error. Eg:

char* arr = new char[5];
strcpy(arr, "Jagan");
delete[] arr;

Instead, allocate arr of length 6 in this case.

Jagannath