チュートリアル、検索、および私の C++ の正式な教育のぼんやりした記憶のせいで、ループ内で動的に割り当てられたオブジェクト ポインターを使用しているときに、どこで delete を使用する必要があるかがわかりません。たとえば、次のようになります。
// necessary files are included, this code is within main
T * t;
t = foo.getNewT();
while (!t->isFinalT()) {
// print t stuff
delete t; // is this where I should delete t?
t = foo.getNewT();
}
delete t;
この知識の欠如は、最近のクラスのプロジェクトで特に厄介になりました。私のラップトップ (Linux Mint、g++ Ubuntu/Linaro 4.7.3-1ubuntu1) では、コードは delete ステートメントなしで正常に実行され、delete ステートメントを追加するとクラッシュしました。学校のサーバー (Solaris、g++ (GCC) 3.4.5) では、delete ステートメントを使用せずに数回繰り返した後にコードがセグメンテーション違反になり、delete ステートメントを追加すると正常に実行されます。
この種のループを適切に処理して、ほとんどの環境で実行するにはどうすればよいですか?
追加情報: プログラムが削除要求に達すると、ラップトップでエラーが発生します。
*** Error in 'program': free(): invalid next size (fast):
...
他のコードの一部:
// T.h
class T {
int id;
int num;
int strVarPos;
char * strVar;
public:
T();
~T();
// + misc. methods
}
// T.cpp
T::T() {
id = 0;
num = -1;
strVarPos = 0;
char * strVar = new char[11];
strVar[0] = '\0'
}
T::~T() {
delete [] strVar;
}
// Foo.cpp
T * Foo::getNewT() {
T * t = new T;
// populate T's fields
return t;
}
解像度:
just と loop を使用した簡単なテストT * t
は正常に機能したため、プロジェクトを空白から再構築し、一度に 1 つのクラスを追加して、いつ問題が発生するかを確認しました。配列の初期化に使用していたサイズ定数を更新せずに、プログラムの他の場所で動的に割り当てられた配列に追加のコンテンツを追加したことがわかりました。
明らかに、学校のサーバーは、ポインターを適切に削除することを確認した場合にのみ、結果として生じるメモリの不一致をクラッシュせずに処理できました (プログラムは、私のテストで重大なメモリ リークを引き起こすほど長く実行されませんでした)。 delete を呼び出そうとするまでのメモリの不一致 (その後クラッシュする)。