2012-02-07 84 views
0

现在,我想用一个函数来增加数组的大小。尝试在C++中动态调整数组大小时崩溃?

#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检查=全./test 2> 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) 

你能在新手来解释这一切?

+1

这可能会有帮助:http://stackoverflow.com/q/9167540/535275 – 2012-02-07 02:51:35

+0

'addr = temp;'不会做你认为它做的事。 – 2012-02-07 02:53:14

+0

我以为addr = temp应该复制temp所持有的东西(因为temp是一个指针,地址到一些堆空间)addr ...猜C++对我来说太困难 – user269334 2012-02-07 05:27:24

回答

3

我相信你的问题是,因为你是按值传递的指针数组的开始,一旦更新并重新分配它,所做的更改不会传播给调用者。如果你改变了功能,因此,它需要通过参考指针,这应该是固定的:

void IncreaseArraySize(int*& addr){ 

现在,你的错误,是因为导致当你main调用

IncreaseArraySize(test); 

test指针回没有被重新分配。因此,一旦你delete[]它在IncreaseArraySize,它引用垃圾内存。更新,使得它通过引用传递参数意味着当在IncreaseArraySize,你说

addr = temp; 

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

希望这会有所帮助!

+0

感谢您的解释:) – user269334 2012-02-07 02:59:23

3

那么最合适的方式来纠正这个代码不使用new所有,只需使用:
std:vector

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

void IncreaseArraySize(int*& addr) 
+0

谢谢!!!这个&sign真的有很大的帮助:D – user269334 2012-02-07 02:58:16

+0

@ user269334:实际上,也应该考虑使用第一个建议,即使将'std :: vector'传递给函数,''也更重要。 Lookup *在C++中通过值传递与传递引用*。 – 2012-02-07 03:00:11