Я использую Embarcadero C++ Builder.Почему удаление указателя TStringList вызывает исключение?
У меня есть функция, которая объявляет TStringList
, использует ее во всей функции, затем delete
s объект в конце функции.
Я успешно использовал этот код в качестве 32-разрядного приложения и преобразовал его в 64-разрядное приложение, и теперь я получаю исключение «Invalid Pointer Operation» при попытке удалить 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;
}
Поскольку вы уже удалили 'List', в вашем' try' -задаче? 'List-> LoadFromFile(); delete List; 'кажется довольно глупым, когда вы повторно используете' List' в блоке после 'catch'. –
У вас в этом коде есть ошибки-после -delete и double -delete, а также утечка памяти. Почему вы 'delete'ing' List' в блоке 'try'? Вы, очевидно, хотите, чтобы он придерживался, чтобы вы могли выполнять операции в цикле 'for' позже. Кроме того, если исключение * * выбрано из блока 'try' и поймано,' List' фактически не будет 'delete'ed. Возможно, более важный вопрос здесь заключается в том, почему вы динамически выделяете «Список» вообще, поскольку, по-видимому, это никогда не должно пережить эту функцию? Просто положите его в стек, и проблема решена. – acwaters
@acwaters, что вы говорите о стеке, как правило, справедливо для чисто кода на C++, но это не чистый код. 'TStringList' - это потомок TObject, а' TObject' может быть создан только в куче, а не в стеке. Это ограничение совместимости компилятора из-за того, что 'TObject' внедряется в Delphi Pascal, и все объекты класса Delphi основаны на куче. –