2012-02-07 85 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