Ваше приложение зависает? Тогда с вашим приложением что-то не так.
Обычно там будет простой AV. AV приводит к сообщению об ошибке. Это все.
Кстати, вы не должны бояться этого - просто справьтесь с этим.
function IsValidObject(const AObj: Pointer { or TObject} ): Boolean;
begin
try
...
// place your checking code there
Result := ...;
except
on EAccessViolation do
Result := False;
end;
end;
Единственное исключение из этого правила, которое приходит на ум, - это если вы пишете какой-то обработчик исключений и хотите определить, существует ли допустимый объект. В этом случае вы, вероятно, не хотите создавать исключение в обработчике исключений;)
Если это ваш случай - попробуйте использовать этот код (это пример):
function GetReadableSize(const AAddress: Pointer; const ASize: Cardinal): Cardinal;
const
ReadAttributes = [PAGE_READONLY, PAGE_READWRITE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE];
var
MemInfo: TMemoryBasicInformation;
Tmp: Cardinal;
begin
Result := 0;
if (VirtualQuery(AAddress, MemInfo, SizeOf(MemInfo)) = SizeOf(MemInfo)) and
(MemInfo.State = MEM_COMMIT) and (MemInfo.Protect in ReadAttributes) then
begin
Result := (MemInfo.RegionSize - (Cardinal(AAddress) - Cardinal(MemInfo.BaseAddress)));
if Result < ASize then
begin
repeat
Tmp := GetReadableSize(Pointer(DWord(MemInfo.BaseAddress) + MemInfo.RegionSize), (ASize - Result));
if (Tmp > 0) then
Inc(Result, Tmp)
else
Result := 0;
until (Result >= ASize) or (Tmp = 0);
end;
end;
end;
function IsValidBlockAddr(const AAddress: Pointer; const ASize: Cardinal): Boolean;
begin
Result := (GetReadableSize(AAddress, ASize) >= ASize);
end;
Но обычно вы предпочитаете первый подход.