2009-05-07 5 views
1

今、私はXMLファイルの解析を処理するシンプルなクラスを用意しています。このようなものになります。C++のクラス間でランタイムサイズの配列を渡すのを処理する方法

int* numbers= data->getInts(); 
///Do things to numbers[] 
delete numbers; 

すべてがすべてをクラッシュdeleteコマンド、までは正常に動作します:プログラムの主要部分で

int* DataParser::getInts(){ 
    *objectNumbers = new int[getSize()]; 
    for (int i=0;i<getSize();i++){ 
      objectNumbers[i]=activeNode->GetNextChild()->GetContent(); 
    } 
    return objectNumbers; 
} 

を、私が行うことで、これを受信します。これを行う正しい方法は何ですか?

答えて

9

問題の一部は、新しい[]とdelete []をペアにしていないことです。これはおそらくあなたのバグの根源ではありませんが、あなたはこれを行ううぬぼれに入るべきです。

バグは、あなたがコメントアウトしたコードとほぼ確実に関連しています。そこにいくつかのコンテキストを追加して、数字の値で何をしているのか分かりますか?

一般的に、私はそれが多くのこのタイプの問題のためのベクトルを使用して簡単だとわかります。これは、メモリ管理を式から排除し、動的メモリを使用してサイズを格納するという追加の利点があります。

void DataParser::getInts(std::vector<int>& objectNumbers){ 
    for (int i=0;i<getSize();i++){ 
     objectNumbers.push_back(activeNode->GetNextChild()->GetContent()); 
    } 
} 

... 
std::vector<int> numbers; 
data.getInts(numbers); 
+0

ありがとうございます、ベクターは明らかに正しい解決策でした。 – mjames

2

次の行は:

*objectNumbers = new int[getSize()]; 

それは何をしますか?あなたがobjectNumbersを返却する場合、これはintへのポインタで、あなたが本当にやるべきこと:

objectNumbers = new int[getSize()]; 

をとにかく、C++は(vectorlistなど)あなたのコレクションを提供します - 私が代わりにそれらのいずれかを使用していたと思いますプレーンな配列の別のところで述べたように、newdeletenew []delete []と一致させることが重要です。

配列を渡すのは良い設計ではありません。つまり、実装を公開することです。イテレータを、STLデザインの代わりに配列/コレクション/シーケンスintの最初と最後に渡してください。

+0

私は彼がint * objectNumbers =を意味するのだろうかと思います... –

+0

このコードがどのようにコンパイルされるのだろうか。 – dirkgently

3

あなたはいつでもあなた

ptr = new Type[...]; 

必ず

delete [] ptr; 

代わりに、通常の

delete ptr; 
で作る

delete [] numbers; 

にルールをされる必要があります

これは未定義の動作になります(Neil Butterworthのおかげで)、配列ではなくptrを指す単一インスタンスの削除を意図しています。

+0

実際には、まったくうまく動作しないかもしれません - C++標準が "未定義の動作"と呼ぶものを与えます。 –

+0

ええ、私は、ptrの削除の意味を伝えようとしていました。しかし、その未定義の振る舞いを含めることは良いことです。ありがとう。 –

1

すぐにトラブルやメンテナンスの問題が発生します。 std :: vectorの使用を検討してください。これは適切な方法です。

2

代わりに単にstd :: vectorを使用してください。

std::vector<int> DataParser::getInts(){ 
    std::vector<int> objectNumbers(getSize()); 
    for (int i=0;i<getSize();i++){ 
      objectNumbers[i]=activeNode->GetNextChild()->GetContent(); 
    } 
    return objectNumbers; 
} 
+0

このコードは、ベクタの内容のコピーを返します。おそらく複数回。 JaredParの例は正しい方法です。ベクトルを参照渡ししてgetIntsに入力します。 – chmike

+1

必ずしもこのコードは、通常は戻り値の最適化のメリットがあります。 – Jem

関連する問題