2012-03-22 14 views
0

配列がいっぱいになると文字列を文字列に格納するC++プログラムを作成しています。以下のコードを使用して、より多くの項目のスペースを確保するために配列のサイズを変更します。しかし時には(必ずしもそうではない)「delete [] temp;」でクラッシュすることがありますなぜ私はそれを修正する方法を知らない。助けてください。C++ delete []クラッシュ

私は多くを検索しましたが、どこでも答えを見つけることができませんでした。私はそれをデバッグするとき "無効なポインタ"と言うが、私は前にデータを格納し、まだそれを解放していないときに無効にすることができますか?

これは私のコードです:

if(item_cnt >= (arr_size - 1)) 
{ 
    int oldsize = arr_size; 
    string * temp; 
    arr_size *= 2; 
    temp = arr; 
    arr = new string [arr_size]; 
    memcpy(arr, temp, oldsize * sizeof(temp)); 
    delete[] temp; 
} 
+2

スタイルのいくつかの点: 'memcpy'ではなく' std :: copy'を使うべきです。また、手動でのメモリ管理( 'new'、' delete'など)を行うべきではないので、コンテナクラスを使ってこれをすべて自動的に処理する必要があります。 –

+3

'memcpy(arr、temp、oldsize * sizeof(temp));' - それは 'sizeof(* temp)'ではいけませんか? (もちろん、memcpyは最初から間違っています) –

+2

これは悪い...文字列にmemcpyを使わないでください。 'string myString(toBeCopied);'を使用してください。.. http://anaturb.net/C/string_exapm.htm –

答えて

0

あなたの配列は本当に

vector<string> 

これは、動的なサイズのアレイを実装するための推奨される方法であるべきです。ベクタを使用することで、手作業によるものの再割り当てやコピーを避け、あなたが持っているような問題を回避できます。

+1

なぜですか?説明が役に立ちます。 –

-1

古いスタイルと新しいスタイルのメモリ操作を混ぜることは常に悪い考えです...ここではmemcpynew/deleteを使用します。あなたは絶対に固執する必要がない限り>デストラクタ

HTH

マリオ

+0

うん、申し訳ありません!あなたは正しいコースです! –

5

- CTOR:

編集... delete[]はまた、配列の各要素に対してデストラクタを呼び出すことに注意してくださいあなたの現在のアプローチ、私はあなたの文字列を保持するベクトルを使用することをお勧めします。それはあなたのためのすべてのメモリを管理します。ここで

は例です:

#include <vector> 
#include <string> 
int main() 
{ 
    std::vector<std::string> arrayOfStrings; 

    arrayOfStrings.push_back("Hello World!"); // To Add Items 
    string value = arrayOfString.at(<some index>); // To Retrieve an Item you can also use the [] operator instead of the at method 

    return 0; 
} 
+0

注:何らかの理由で配列を指す必要がある場合でも、ベクトルを使用して、ポインタが必要な場所で '&arrayOfStrings [0]'を渡すことができます。 – cHao

+0

実際、それは私の宿題です(私はそれは不正行為と呼ばれるかもしれませんが、私が記述した行動の理由を本当に見つけることができませんでした)、ここでベクターを使用することは許されません。とにかくチップのおかげで – Dalibor

1

memcpyはあなたの問題の根本です。誰もが "それを使わないでください"と言いましたが、なぜそれが最終的に悪い考えであるか正確に説明しましょう。

最初に、C++の文字列とは何ですか?その魔法はどのようにして動作しますか?これは、基本的に可変長の文字配列であり、各文字列オブジェクト内に、それらの文字を保持するために割り当てられたメモリを指すポインタを保持することによって、この偉大さを実現します。文字列が拡大または縮小すると、そのメモリが再割り当てされます。文字列を正しくにコピーすると、内容の「ディープコピー」が作成されます。

今、あなたのコードに:

arr = new string [arr_size]; 

これは、空の文字列オブジェクトの配列を作成します。それらは空であるため、内部ポインタは通常nullです。

memcpy(arr, temp, oldsize * sizeof(temp)); 

ここでは、悪いことが起こります。これは実際に元の文字列のコピーを作成するのではなく、内部表現を上書きするだけです。したがって、古い文字列と新しい文字列の両方が同じ文字データを指しています。私たちは、thew古い文字列を削除

delete[] temp; 

が、これはまた、彼らは使用していた文字のメモリを解放:今本当にネジ物事に、これが起こります。だから、これらの文字列の私たちの新しいコピーは、実際に解放されたメモリを指しています。文字列データを何かのために再利用できるようになり、文字列をもう一度やり直してみると、オペレーティングシステムは、あなたが持っていないメモリを解放しようとしていることに気付くでしょう。割り当てられた。

関連する問題