私はEmbarcadero C++ Builderを使用しています。TStringListポインタを削除すると例外がスローされるのはなぜですか?
私はTStringList
を宣言し、関数全体でそれを使用する関数を持っています。そして、関数の最後にオブジェクトdelete
があります。
このコードを幸せに32ビットアプリケーションとして使用していて、これを64ビットアプリケーションに変換しましたが、TStringList
を削除しようとすると「無効なポインタ操作」例外が発生します。何か案は?
私は文字ポインタ(ヒープメモリ空間を作成するためにnew
を使用)と操作delete
を使用する別の関数で同じ問題を抱えていました。私は、その関数のスタックスペースを持つローカルバッファを作成してしまったが、私はTStringList
オブジェクトを使用したいので、この1つに固執している。あなたのコードは、二回delete
List
にあなたを引き起こし、それにロジックのバグを持っている、またはそれを完全に漏れて、コメントで述べたように
String ReadUserConfig(String ConfigString) {
String UserConfigPath = AppDrive + "\\DC\\userconfig.csv";
TStringList *List = new TStringList;
if (FileExists(UserConfigPath)) { // file present, parse it
try {
List->LoadFromFile(UserConfigPath);
delete List;
}
catch(...) {
ShowMessage("Exception in ReadUserConfig()");
return ReturnString;
}
for (int i = 0; i < List->Count; ++i) {
String thisLine = List->Strings[i];
/* search for ConfigString in this line */
if ((thisLine.Pos(ConfigString) != 0) &&
(thisLine.Pos("USER_CONFIG") != 0)) {
/* grab everything right of ConfigString */
thisLine = thisLine.SubString
(thisLine.Pos(ConfigString) + ConfigString.Length() + 1,
thisLine.Length());
ReturnString = thisLine.Trim();
i = List->Count;
}
}
}
delete List; /* CAUSES INVALID POINTER EXCEPTION */
return ReturnString;
}
'List'をすでに削除しているので、' try'文では? 'List-> LoadFromFile();リストを削除する; '' catch'の後のブロックで 'List'を繰り返し使用しているとき、かなり愚かなようです。 –
このコードでuse-after -deleleteとdouble -delete'バグとメモリリークがあります。 'try'ブロックで' List'を 'delete'しているのはなぜですか?後で 'for'ループで操作を行うことができるように、あなたはそれを固執しておきたいと思います。さらに、 'try'ブロックから例外がスローされ捕捉された場合、' List'は実際には 'delete'されません。しかし、ここで重要なのはおそらく、なぜこの関数を永久に失うことはないと思われるので、あなたは動的に 'List'を割り当てているのでしょうか?スタックに置くだけで問題は解決します。 – acwaters
@acwatersスタックについて言うことは、純粋なC++コードでは一般的に当てはまりますが、これは純粋なコードではありません。 'TStringList'は' TObject'子孫であり、 'TObject'はスタックではなくヒープ上でのみ構築できます。これは、 'TObject'がDelphi Pascalに組み込まれているため、コンパイラの互換性の制限です。すべてのDelphiクラスオブジェクトはヒープベースです。 –