![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
отличия Assign от p<>nil
денизко © (2007-10-09 17:24:00)Объясните дураку зачем нужна ф-ция Assign, если можно написать
if p<>nil then ...
И как все таки узнать был ли убит объект, если после вызова деструктора Free, переменная-объект по-прежнему не nil и указывает на недоступный кусок памяти?
денизко (2007-10-09 20:26:00) [21]
> MetalFan ©
О! А можно поподробней? Что находится по адресу LongInt(P) - 4
Johnmen (2007-10-09 19:41:00) [22]Солидарен с Суслик © (09.10.07 18:25) [11], так удобней.
MetalFan (2007-10-09 19:18:00) [23]нет, лучше такое:
function CheckIsFreed( AObject: TObject ): Boolean;
var
Signature: PLongInt;
P: Pointer;
begin
P := AObject;
Result := P = nil;
if Result then Exit;
Signature := PLongInt(LongInt(P) - 4);
Result := IsBadReadPtr( Signature, 4 );
if result then Exit;
Result := Signature^ = 1;
end;
и тесткод:
procedure TForm1.Button1Click(Sender: TObject);
var
lSL : TStringList;
begin
Integer(lSL) := 123123123;
ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
lSL := TStringList.Create;
ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
lSL.Free;
ShowMessage( BoolToStr( CheckIsFreed( lSL), True ));
end;
MetalFan (2007-10-09 19:15:00) [24]а как вам нечто такое?
function CheckIsFreed( AObject: TObject ): Boolean;
var
Signature: PLongInt;
P: Pointer;
begin
P := AObject;
Result := P = nil;
if Result then Exit;
Signature := PLongInt(LongInt(P) - 4);
Result := Signature^ = 1;
end;
Суслик (2007-10-09 18:25:00) [25]
> [9] Ega23 © (09.10.07 18:02)
> > в многопоточном можно нарваться, хотя и маловероятно
> Это как?????
я нарывался как в [10] описано.
------------
по сабжу - я не пишу Assigned никогда, всегда <> nil пишу.
удобней мне так
clickmaker (2007-10-09 18:07:00) [26]procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
сравни последовательность операций.
Представь, что деструктор начал выполняться, а другой поток с чистой совестью, проверив, что <> nil, полез работать с объектом...
Ega23 (2007-10-09 18:02:00) [27]
> в многопоточном можно нарваться, хотя и маловероятно
Это как?????
clickmaker (2007-10-09 18:00:00) [28]
> можно тупо заменить на
> Obj.Free;
> Obj := nil;
в многопоточном можно нарваться, хотя и маловероятно
Ega23 (2007-10-09 17:55:00) [29]
> Второй вопрос открыт: известны ли кому-нибудь способы, как
> узнать был ли убит объект, если он был убит НЕ FreeAndNil
> а банальным деструктором Free?
Перехват исключения.
А вообще - просто не следует такого допускать ещё при проектировании.
И, кстати, FreeAndNil(Obj) можно тупо заменить на
Obj.Free;
Obj := nil;
денизко (2007-10-09 17:49:00) [30]Тьфу, не Assign, Assigned конечно.. торопился..
> Сергей М.
> Если возникло исключение EAccessViolation
т.е. бороться с ним в блоке try except? смущает громоздкий код:
если б Assigned позволяла определить существование объекта я бы обошелся одной лаконичной строкой:
if Assigned(p) then p.DoIt;
с try except будет 4:
try
p.DoIt;
except
end;
можно конечно все в одну уложить но... не нравится и все тут! :)
Правильный Вася (2007-10-09 17:48:00) [31]
> ф-ция Assign
вообще-то это метод, и делает он вещи прямо противоположные описанным тобой
Сергей М. (2007-10-09 17:43:00) [32]
> известны ли кому-нибудь способы, как узнать был ли убит
> объект
Нет иных способов, нежели перехват исключения.
Да и не надо ничего узнавать, просто не следует допускать "убийство" объекта без соответствующей немедленной коррекции всехсуществующих ссылок на него.
денизко (2007-10-09 17:36:00) [33]
> clickmaker ©
Спасибо за ответ.
Хелп я читал и с FreeAndNil знаком.
Т.е. получается что Assigned только для того и нужна, чтобы в нее можно было пихать как указатели так переменные процедурного типа? Хм, лично мне не сложно и ручками написать @P <> nil, но это не важно... С этим понятно..
Второй вопрос открыт: известны ли кому-нибудь способы, как узнать был ли убит объект, если он был убит НЕ FreeAndNil а банальным деструктором Free?
Сергей М. (2007-10-09 17:31:00) [34]
> ачем нужна ф-ция Assign, если можно написать
> if p<>nil then ...
>
Встречный вопрос - зачем писать
if p<>nil then ...
если можно написать
if Assign ed(p) then ...
?
На первое время считай, что разницы никакой.
> узнать был ли убит объект
Если возникло исключение EAccessViolation или EInvalidPointer, то объект 100%-но "убит".
Вероятность же невозникновения одного из этих исключений при гарантированно "убитом" объекте ничтожно мала.
clickmaker (2007-10-09 17:29:00) [35]Assigned(P) corresponds to the test P<> nil for a pointer variable, and @P <> nil for a procedural variable (c) F1
> переменная-объект по-прежнему не nil
FreeAndNil()