Вот упрощенный контекст кода для моего вопроса:
TSomeone = record
FirstName: String;
LastName: String;
Picture: TGraphic;
end;
TSomeoneHelper = record helper for TSomeone
public
procedure Clear();
procedure LoadFromFile(const Filename: String);
end;
procedure TSomeoneHelper.Clear();
begin
Self.FirstName := '';
Self.LastName:= '';
try
if Assigned(Self.Picture) then
FreeAndNil(Self.Picture); // <---- Crash here in 64-bit release
except
Self.Picture := nil;
end;
end;
Обычно кто-то объявляет переменную TSomeone
, а затем вызывает myVar.LoadFromFile('myfile.blah')
для заполнения записи. В процедуре LoadFromFile
создается TJPEGImage
(TGraphic
потомок), который затем назначается Picture
.
Поскольку я не в классе (нет конструктора в record helper
), у меня есть нет возможности инициализировать Picture
как nil
. Из-за этого FreeAndNil
вылетает. Что странно, так это то, что в 32-битных сборках он кажется инициализированным nil
, но в 64-битных - нет (это «Недоступное значение»). По этой причине я добавил try except
. Но что еще более странно в 64-битной версии, я получаю нарушение прав доступа, которое не улавливается try except
.
Подводя итог:
- 32-битная версия + отладочные сборки Хорошо, так как
Picture
инициализируется как nil
, потому что magi c (?), Так что никаких исключений - все в порядке - 64-битная отладка
Picture
инициализируется «Недоступное значение», которое запускает Assigned
тогда FreeAndNil
делает нарушение прав доступа, но try
его ловит, так что все в порядке - 64-разрядная версия (не знаю, как отлаживать сборку процессора, поэтому не знаю, что происходит), но
try
не улавливайте нарушение прав доступа, и ошибка выдается пользователю так плохо
Что я могу сделать, чтобы исправить это?