2016-12-07 1 views
2

У меня есть этот код в VCL Forms Application:Нарушение прав доступа при освобождении переменной TBitmap - переменная битмапа по-прежнему назначается после освобождения?

implementation 

{$R *.dfm} 

var 
    MyBitmap: TBitmap; 

procedure TFormMain.FormCreate(Sender: TObject); 
begin 
    MyBitmap := TBitmap.Create; 
end; 

procedure TFormMain.FormDestroy(Sender: TObject); 
begin 
    if Assigned(MyBitmap) then 
    MyBitmap.Free; 
end; 

procedure TFormMain.Button1Click(Sender: TObject); 
begin 
    if Assigned(MyBitmap) then 
    MyBitmap.Free; 
end; 

При нажатии на кнопку второй раз, я получаю нарушение прав доступа в MyBitmap.Free; в обработчик щелчка кнопки. Но MyBitmap больше не следует назначать после первого нажатия кнопки. Итак, почему условие if Assigned(MyBitmap) then не работает над второй кнопкой, когда она, очевидно, работает на первой кнопке?

Delphi 10,1 Berlin Update 2

+1

Назначенные проверки на равенство нулю, освобождение ссылки на объект не делает его нулевым. Следовательно, вы пытаетесь сделать двойной доступным. –

+0

Кажется, что 'System.SysUtils.FreeAndNil (MyBitmap)' выполняет работу без AV. – user1580348

+0

Итак, окончательно мы узнали: OBJECT может быть освобожден с помощью 'FREE', а OBJECT VARIABLE можно установить на' NIL', а не наоборот. Это верно? – user1580348

ответ

6

Assigned функция проверяет только указатель будет Nil. Он не выполняет проверку, указывает ли он на существующий объект или нет. Вы должны установить его на Nil, освободив его, чтобы получить функцию Assigned, как вы ожидаете. FreeAndNil выполняет обе инструкции.

+0

Есть ли общее правило, когда использовать 'Free' и когда использовать' FreeAndNil' при выпуске переменной объекта? – user1580348

+0

@user - Если есть вероятность того, что объект может быть освобожден из нескольких мест, FreeAndNil может быть полезен. Но это не очень распространено. –

+2

Это мнение основано. IMHO вы должны установить ссылку на объект на «Nil» после освобождения, когда доступ к переменной можно получить после освобождения ссылочного объекта. Таким образом, вам не нужны локальные переменные «Nil» в методе, когда ничего не произойдет после «Free». После этого никто не может получить доступ к этим переменным. То же самое относится к объектным ссылкам, хранящимся в переменных-членах класса и которые освобождаются в своем деструкторе. Но вы должны «Ниль» их дополнительно, когда вы «освобождаете» их во время жизни этого объекта (например, освобождая член формы внутри нажатия кнопки). – Wosi

Смежные вопросы