Почему удаление указателя TStringList вызывает исключение?

Я использую Embarcadero C ++ Builder.

У меня есть функция, которая объявляет TStringList, использует его во всей функции, затем deletes объект в конце функции.

Я с удовольствием использовал этот код в качестве 32-разрядного приложения и преобразовал его в 64-разрядное приложение, и теперь я получаю исключение «Недопустимая операция указателя» при попытке удалить TStringList, Есть идеи?

Странно то, что у меня была такая же проблема с другой функцией, которая использует символьный указатель (используя new создать кучу памяти) и delete операция. Я закончил тем, что создал локальный буфер с пространством стека для этой функции, но я застрял с этим, так как я хотел бы использовать TStringList объект.

Вот код:

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

0

Решение

Как указано в комментариях, в вашем коде есть логические ошибки, заставляющие вас delete List дважды или полностью утечка.

Попробуйте что-то более похожее на это:

String ReadUserConfig(String ConfigString) {
String UserConfigPath = AppDrive + "\\DC\\userconfig.csv";

try {
TStringList *List = new TStringList;
try {
if (FileExists(UserConfigPath)) { // file present, parse it
List->LoadFromFile(UserConfigPath);

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();
break;
}
}
}
}
__finally {
delete List;
}
}
catch(const Exception &e) {
ShowMessage("Exception in ReadUserConfig()\n" + e.Message);
}
catch(...) {
ShowMessage("Exception in ReadUserConfig()");
}

return ReturnString;
}

Или используйте std::auto_ptr (до C ++ 11) или std::unique_ptr (C ++ 11 и выше) вместо try/finally блок:

#include <memory>

String ReadUserConfig(String ConfigString) {
String UserConfigPath = AppDrive + "\\DC\\userconfig.csv";

try {
//std::auto_ptr<TStringList> List(new TStringList);
std::unique_ptr<TStringList> List(new TStringList);

if (FileExists(UserConfigPath)) { // file present, parse it
List->LoadFromFile(UserConfigPath);

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();
break;
}
}
}
}
catch(const Exception &e) {
ShowMessage("Exception in ReadUserConfig()\n" + e.Message);
}
catch(...) {
ShowMessage("Exception in ReadUserConfig()");
}

return ReturnString;
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]