2011-01-20 13 views
0
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; 
} 

スープ人。私は/ r /私は自分のコードで持っているこの問題の助けを払っています。どうやら私のC++コードの何かがヒープ破損エラーを引き起こしていて、何かはdelete[] catです。 catは、新しい演算子とポインタで作成されたintの動的配列です。なぜ、私が配列を削除すると、プログラム全体がスチームローラーの下で粉砕され、ヒープの破損が起こったと判断するのですか?私は12歳ですが、これは何ですか?ヒープの破損?私のダイナミックメモリで?

+6

-1 4chanの上4chanの保管してください。 (とにかくしようとするなら、少なくとも新しいものにはならない--- ...) – GManNickG

+0

ルール1とルール2は分かりませんか? –

+0

これは基本的にC++を使用するための規則です。すべての行はスチームローラーです。 – ActiveTrayPrntrTagDataStrDrvr

答えて

3

あなたは関数内の変更が外部に反映されないように、値によってcatポインタを渡しています。ポインタをint*& catのように参照渡しする必要があります。

+0

ありがとうございますが、動作しませんでした。 – im12andwhatisthis

+1

まだヒープの破損が発生していますか?この関数を呼び出すコードを投稿することができます。 – Naveen

+0

catを一度削除しておけば、値をいくつかコピーする前にメモリを割り当てる必要はありません。 – ckv

1

catではありません。はこの関数の呼び出し元に返されます。 cat = longcatを実行すると、ローカルコピーのみが変更されます。

これは、この関数に渡したパラメータが、あなたが非常に不便に削除した古いアドレスを指していることを示しています。

参照として渡すか、古いCダブルポインタをトリックしてそのアドレスを渡します。

はまた、あなた破損しているメモリといけないあなたはこれを呼び出して初めて、catが有効な値を持っていることとsizelooongは(looong * 2 >= size)互換性があることを確認することをお勧めします。

はあなたの問題を示し、次のコードを見てください:

#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; 
} 

その出力は次のようになります。longcatislong1呼び出しが正常復帰にctを設定しなかったことを意味

0 
0 
0x9c83060 

。参照としてポインタを渡すlongcatislong2関数は、を実行し、を正しく設定します。ctです。


0xf0000000への有効なポインタがあるとします。元の関数を呼び出すと、新しいメモリブロックが割り当てられ、データがコピーされ、古いブロックが削除されます。

しかし、変数ctは、まだ古いブロックを指しています。

次の他の場所でctを参照解除する場合でも、一般に未定義の動作と呼ばれる苦痛の世界に入ります。最初のパラメータに参照型にすることにより

、関数の中で行われた変更は、バックに渡された変数に反映されている。

0

あなたは*関数引数のintによって猫**猫、その後、int型を削除する必要がありますcat [i]配置でも* catによってすべてのcat挿入 を関数本体に置き換えます。その後、

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; 
} 

そして、あなたがそのようにそれを呼び出す関数を呼び出す:

longcatislong(&cat, size, looong); 
+0

CまたはC++でコード化してください。同時に両方ではありません: – paxdiablo

+0

CはC++と完全に互換性がありますが、なぜポインタへのポインタがC++でないと思いますか? – Ilay

+0

@paxdiablo:動的にサイズ変更された配列を実装するのは、C++ではありません。 – ybungalobill

関連する問題