尝试在C ++中动态调整数组大小时崩溃?

时间:2012-02-07 02:48:28

标签: c++ arrays new-operator delete-operator

现在,我想使用函数增加数组的大小。

#include <iostream>
using namespace std;

void IncreaseArraySize(int* addr){
    int* temp = new int[20];
    for(int i=0;i<10;i++){
        temp[i] = addr[i];
    }
    for(int i=10;i<20;i++){
        temp[i] = i;
    }
    int* dummy = addr;
    addr = temp;
    delete[] dummy;
}

int main(){
    int* test = new int[10];
    for(int i=0;i<10;i++){
        test[i] = i;
    }
    IncreaseArraySize(test);
    for(int i=0;i<20;i++){
        cout<<"at index "<<i<<"we have"<<test[i]<<endl;
    }
    cout<<"ok!"<<endl;
    delete[] test;
}

我用以下代码运行代码: valgrind --leak-check = full ./test 2&gt; debug.txt

这就是我输出的结果:

at index 0we have0
at index 1we have1
at index 2we have2
at index 3we have3
at index 4we have4
at index 5we have5
at index 6we have6
at index 7we have7
at index 8we have8
at index 9we have9
at index 10we have0
at index 11we have0
at index 12we have0
at index 13we have0
at index 14we have0
at index 15we have0
at index 16we have0
at index 17we have0
at index 18we have112
at index 19we have0
ok!

这就是我在debug.txt上得到的:

==4285== Memcheck, a memory error detector
==4285== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4285== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==4285== Command: ./test
==4285== 
==4285== Invalid read of size 4
==4285==    at 0x400997: main (test.cpp:24)
==4285==  Address 0x596f040 is 0 bytes inside a block of size 40 free'd
==4285==    at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285==    by 0x400931: IncreaseArraySize(int*) (test.cpp:14)
==4285==    by 0x400980: main (test.cpp:22)
==4285== 
==4285== Invalid free() / delete / delete[]
==4285==    at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285==    by 0x400A16: main (test.cpp:27)
==4285==  Address 0x596f040 is 0 bytes inside a block of size 40 free'd
==4285==    at 0x4C27C6E: operator delete[](void*) (vg_replace_malloc.c:409)
==4285==    by 0x400931: IncreaseArraySize(int*) (test.cpp:14)
==4285==    by 0x400980: main (test.cpp:22)
==4285== 
==4285== 
==4285== HEAP SUMMARY:
==4285==     in use at exit: 80 bytes in 1 blocks
==4285==   total heap usage: 2 allocs, 2 frees, 120 bytes allocated
==4285== 
==4285== 80 bytes in 1 blocks are definitely lost in loss record 1 of 1
==4285==    at 0x4C2864B: operator new[](unsigned long) (vg_replace_malloc.c:305)
==4285==    by 0x4008A9: IncreaseArraySize(int*) (test.cpp:5)
==4285==    by 0x400980: main (test.cpp:22)
==4285== 
==4285== LEAK SUMMARY:
==4285==    definitely lost: 80 bytes in 1 blocks
==4285==    indirectly lost: 0 bytes in 0 blocks
==4285==      possibly lost: 0 bytes in 0 blocks
==4285==    still reachable: 0 bytes in 0 blocks
==4285==         suppressed: 0 bytes in 0 blocks
==4285== 
==4285== For counts of detected and suppressed errors, rerun with: -v
==4285== ERROR SUMMARY: 22 errors from 3 contexts (suppressed: 4 from 4)

你能用新手来解释一下吗?

2 个答案:

答案 0 :(得分:3)

更正此代码的最合适方法是根本不使用new,只需使用:
std:vector

此外,特别是您的代码的问题是您正在通过值传递指针addr,这会创建一个临时代码并将其传递给函数。在函数内对此指针所做的任何更改都是在指针的副本而不是原始指针上进行的。您需要addr引用,以便函数内部的更改在指针上进行并反映在指针之外功能

void IncreaseArraySize(int*& addr)

答案 1 :(得分:3)

我相信你的问题是因为你通过值将指针传递给数组的开头,一旦你更新并重新分配它,更改就不会传播给调用者。如果更改函数以使其通过引用获取指针,则应修复此问题:

void IncreaseArraySize(int*& addr){

目前,您的错误是由于您致电

造成的
IncreaseArraySize(test);

test中的main指针未被重新分配。因此,一旦delete[]中的IncreaseArraySize,它就会引用垃圾内存。更新参数以使其通过引用传递意味着在IncreaseArraySize中,当您说

addr = temp;

这将更新test中的main指针,防止错误。

希望这有帮助!