开发者

Heap corruption? In MY dynamic memory?

void longcatislo开发者_C百科ng(int* cat, int &size, int &looong)
{
    int* longcat = new int[looong*2];
    for(int i = 0; i < size; i = i + 1)
        longcat[i] = cat[i];
    delete [] cat;
    cat = longcat;
    looong = looong * 2;
}

Soup guys. I'm /r/equesting some help with this problem I have with my code. Apparently something in my C++ code caused a heap corruption error and that something is delete[] cat. cat is a dynamic array of ints that was created with the new operator and a pointer. Why, then is it that when I use the array delete the whole program decides to get crushed under a steamroller and say I got heap corruption. I'm 12 and what is this?


You are passing cat pointer by value so whatever changes you do inside the function is not reflected outside. You need to pass the pointer by reference like int*& cat.


cat is not being returned to the caller of this function. You're only changing the local copy when you execute cat = longcat.

That means the parameter that you passed in to this function still points to the old address which you've very inconveniently deleted.

Either pass it in as a reference or do the old C double pointer trick and pass in its address.

You may also want to ensure that the first time you call this, cat has a valid value and that size and looong are compatible (looong * 2 >= size) lest you corrupt memory.

Have a look at the following code which illustrates your problem:

#include <iostream>
void longcatislong1(int* cat, int &size, int &looong)
{
    int* longcat = new int[looong*2];
    for(int i = 0; i < size; i = i + 1)
        longcat[i] = cat[i];
    delete [] cat;
    cat = longcat;
    looong = looong * 2;
}

void longcatislong2(int*& cat, int &size, int &looong)
{
    int* longcat = new int[looong*2];
    for(int i = 0; i < size; i = i + 1)
        longcat[i] = cat[i];
    delete [] cat;
    cat = longcat;
    looong = looong * 2;
}

int main (void) {
    int sz = 0;
    int lng = 10;
    int *ct = 0;
    std::cout << ct << std::endl;
    longcatislong1 (ct, sz, lng);
    std::cout << ct << std::endl;
    longcatislong2 (ct, sz, lng);
    std::cout << ct << std::endl;
    return 0;
}

Its output is:

0
0
0x9c83060

meaning that the longcatislong1 call did not successfully set ct on return. The longcatislong2 function, which passes the pointer in as a reference, does set ct correctly.


So let's say you have a valid pointer to 0xf0000000. When you call your original function, a new memory block is allocated, the data is copied across and the old block is deleted.

But the ct variable still points to the old block.

The next time you call the function, or even if you dereference ct elsewhere, you're in for a world of pain, commonly called undefined behaviour.

By making the first parameter a reference type, changes made in the function are reflected back in the variable that was passed in.


You should remove int* cat by int** cat in function args, and then replace all cat insertions in function body by *cat even in cat[i] placement.

void longcatislong(int** cat, int &size, int &looong)
{
    int* longcat = new int[looong*2];
    for(int i = 0; i < size; i = i + 1)
        longcat[i] = *cat[i];
    delete [] *cat;
    *cat = longcat;
    looong = looong * 2;
}

And then when you call function call it like that:

longcatislong(&cat, size, looong);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜