2012-02-07 3 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; 
} 

私は、コードを実行しました:

DEBUG.TXT> valgrindの2 ./testフル= --leak-チェックして、これは私が出力のために得たものである:

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 –

+0

'addr = temp;'はあなたの考えをしません。 –

+0

私はaddr = tempがaddrにtempが保持しているもの(tempはポインタ、あるヒープスペースのアドレスなので)をコピーするはずだと思っていました... C++があまりにも混乱していると思います – user269334

答えて

3

私はあなたの問題は、あなたが更新され、それを再割り当てしたらあなたは、値によって配列の先頭へのポインタを渡しているので、変更が呼び出し元に伝播していないことであると信じています。それは参照することにより、ポインタを取るようにあなたが機能を変更した場合、これは固定する必要があります。

void IncreaseArraySize(int*& addr){ 

今あなたが戻ってmain

IncreaseArraySize(test); 

testポインタを呼び出すときので、あなたのバグが原因です再割り当てされていません。その結果、delete[]になると、それはIncreaseArraySizeになります。ガベージメモリを参照します。それは参照によって渡されていますので、パラメータを更新するIncreaseArraySizeに、あなたは

addr = temp; 

を言うとき、これはバグの防止、maintestポインタを更新することを意味します。

希望すると便利です。

+0

ありがとう:) – user269334

3

さて、このコードをまったくnewを使用しないようにされて修正するための最も適切な方法だけを使用します。
std:vector

また、特にあなたのコードの問題は、あなたがポインタaddrを渡しているということです値によって、一時的に作成され、それを関数に渡します。関数内でこのポインタに加えられた変更は、元のポインタではなくポインタのコピーに対して行われます。addrが参照されているため、関数内の変更はポインタ上で行われ、関数の外部に反映されます。

void IncreaseArraySize(int*& addr) 
+0

thanks !!! D – user269334

+0

@ user269334:実際には、 'std :: vector'を関数に渡したとしても、最初の提案を使用することをお勧めします。ルックアップ*値渡しと参照渡し*をC++で渡す。説明のために –

関連する問題