+86
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
function IsMemoryCommitByAdress(const AAddress: Pointer): Boolean;
var
MemoryInfo: TMemoryBasicInformation;
begin
Result := False;
if not Assigned(AAddress) then
Exit;
VirtualQuery(AAddress, MemoryInfo, SizeOf(MemoryInfo));
Result := MemoryInfo.State and MEM_COMMIT <> 0;
end;
function IsPointerToVMT(const APointer: Pointer): Boolean;
var
VMTPointer, VMTPointerSelf: Pointer;
begin
Result := False;
if not IsMemoryCommitByAdress(APointer) then
Exit;
VMTPointer := APointer;
VMTPointerSelf := Pointer(Integer(VMTPointer) + vmtSelfPtr);
if not IsMemoryCommitByAdress(VMTPointer) then
Exit;
if not IsMemoryCommitByAdress(VMTPointerSelf) then
Exit;
if not IsMemoryCommitByAdress(PPointer(VMTPointerSelf)^) then
Exit;
Result := PPointer(VMTPointerSelf)^ = VMTPointer;
end;
function IsBadptr(apointer:pointer):boolean;
begin
Result := IsMemoryCommitByAdress(APointer) and IsPointerToVMT(PPointer(APointer)^);
end;
Функция, для определения качества указателя, в ситуации "один объект - несколько указателей".
Гк в том, что нет надежности - это все равно, что юзать IsBadReadPtr и аналогичные.
Почему-то никто не пытается использовать операторы is и as (я узнал о них благодаря Тарасу, спасибо ему), чтобы сравнить качество приведения.
Запостил: brutushafens,
19 Июня 2014
laMer007 19.06.2014 10:39 # 0
bormand 19.06.2014 11:16 # +1
bormand 19.06.2014 11:16 # 0
А не проще не ложить в указатели мусор и не забывать занилять их, есил память освободили?
> is и as
is и as запросто могут крашнуться на мусорном указателе. Разве нет?
tirinox 19.06.2014 12:54 # +1
bormand 19.06.2014 13:04 # 0
kipar 19.06.2014 13:05 # 0
kipar 19.06.2014 11:20 # +1
И как по-твоему работает is?
Точно также, он обращается к указателю как к объекту и пытается прочитать по отрицательному смещению указатель на vmt.
Только я сомневаюсь что он проверяет выделена ли данная память (в fpc не проверяет), соответственно если вместо указателя передали случайное число, то программа с "is" крашнется, а эта процедура вернет false.
---
Вот краш: http://ideone.com/jAE6Oq
brutushafens 19.06.2014 16:13 # +1
kipar 19.06.2014 17:04 # 0
получаем Runtime Error. Потому что обратились по некорректному адресу.
brutushafens 19.06.2014 17:08 # +1
bormand 19.06.2014 17:19 # +1
Как я и писал выше - просто никогда так не делать. Заранее продумай, кто будет отвечать за жизнь объекта и как эта ответственность будет передаваться, и проблемы не будет. Ну либо реализуй/найди потокобезопасный подсчет ссылок, раз уж сборщика мусора нету в делфи.
А as и is совсем не для этого придуманы. Они нужны на случай, если ты указатель на какой-нибудь TStringList кастанул в TObject и хочешь проверить - а правда ли это не просто TObject, а именно TStringList. Ну и кастануть в обратную сторону... Для мусорных указателей они совершенно не предназначены, это UB, как любят говорить крестовики.
brutushafens 19.06.2014 17:37 # +1
bormand 19.06.2014 17:42 # 0
Ну как вариант - просто помечай их каким-нибудь флагом вместо удаления. Либо отдавай объекты потокам насовсем, а поток при завершении пусть втыкает результаты в какойнить потокобезопасный список.
Ну либо отдавай потоку не объект а какой-нибудь идентификатор (раз объект все равно не юзаешь). И если item'а с таким идентификатором нет - просто забивай на результат.
Либо перед удалением айтема сначала останови соотв. поток.
Вариантов дохера, на самом деле ;)
brutushafens 19.06.2014 17:48 # +2
Soul_re@ver 20.06.2014 18:33 # 0
dynamic_cast в Дельфи? Нахрен им это говно сдалось? Лучше так ничего и не придумали?
Sim_salapim 19.03.2018 23:39 # 0
SemaReal 19.03.2018 23:42 # 0
Sim_salapim 19.03.2018 23:49 # 0
SemaReal 19.03.2018 23:55 # 0