powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Улучшил FreeAndNil. Можете не благодарить.
25 сообщений из 226, страница 7 из 10
Улучшил FreeAndNil. Можете не благодарить.
    #39954971
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
объект пошёл на удаление - нефиг к нему лезть по глобальным переменным, только по эксклюзивному доступу (передавая указатель на себя) подписчикам

Это все правильно, но не всегда есть возможность заставить всех так делать. При этом имеем ситуацию, когда Free + nil работает идеально, ничего не течет, не крашится, и "математически" стабильно, а FreeAndNil -- мгновенно AV, которое без переписывания половины проекта не побороть.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954974
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
В случае класса, где из деструктора вызывается обработчик события, логично ожидать

Прежде всего, "логично ожидать" - это не метод надёжного программирования. Метод надёжного программирования - проверять, убеждаться и стараться строить взаимодействие так, чтобы не сломалось в будущем, когда те или иные аспекты реализации могут и переделать.

Во вторую очередь, к тому объекту, у которого только что вызван деструктор и который ещё находится во вменяемом состоянии, действительно можно обращаться - и на это, как вполне справедливо заметил Няшик, вполне хватит Sender-а. В отношении его окружения, то есть Owner-а, других компонент в том же Owner-е итп. такое утверждение уже неверно, обращаться нельзя. Поэтому вопрос обращения через глобальные переменные неактуален. Вообще, при написании обработчиков типа OnDestroy надо тщательно продумывать, что делаешь, каким способом и нельзя ли это вынести куда-нибудь пораньше.

И наконец, глобальное преимущество FreeAndNil в том, что она оставляет разрушаемый объект в относительно адекватном состоянии в ходе разрушения. То есть, когда случается какая-либо непредусмотренная разработчиками петля, приложение в лучшем случае проверяет на if Assigned и корректно работает дальше, в худшем не проверяет и напарывается на простой и очевидный AV, но не начинает веселухи работы через уже освобождённую память.

misha mike
Что касается логики работы FreeAndNil, то она в стремлении не допустить даже кратковременного существования ссылки на мертвый объект, улетает в другую крайность:

Верно. И в данном случае это хорошая и правильная крайность. Она заставляет явно продумать места, где возникают сложности, а не полагаться на то, что "в этот раз вроде сработало".

misha mike
допускает существование живого и еще работающего объекта при мертвой ссылке. И это тоже неконсистентное состояние программы, хоть и несущее меньше потенциальных проблем.

Оно действительно несёт кардинально меньше потенциальных проблем, это главное (к ранее упоминавшемуся вопросу про правильный порядок действий). Но кроме этого, Вы неправы, называя такое состояние неконсистентным. В том состоянии, о котором идёт речь, затёрты внешние ссылки (и это правильно), но остаются оперативные, недоступные извне - грубо говоря, Self в регистрах и всё, что от него растёт. Это как раз то, что нужно для завершения уничтожения объекта, не более и не менее.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954977
ma1tus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
В случае класса, где из деструктора вызывается обработчик события, логично ожидать, что
событие будет называться, хотя бы - "OnDestroing". По-хорошему, деструктор надо держать в чистоте-теплоте-сухости и не вызывать оттуда методы взаимодействия с объектом, а для уведомлений о разрушении - из BeforeDestruction или через FreeNotification.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954978
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
Что касается логики работы FreeAndNil, то она в стремлении не допустить даже кратковременного существования ссылки на мертвый объект, улетает в другую крайность: допускает существование живого и еще работающего объекта при мертвой ссылке. И это тоже неконсистентное состояние программы, хоть и несущее меньше потенциальных проблем.

Каком образом после FreeAndNil может остаться живой объект?..
А про мёртвую ссылку - при вызове любых событий из деструктора, туда должен передоваться Self как Sender - на это FreeAndNil не влияет никак и ссылка будет жива.
misha mike
У нас из деструктора вызывается внешний обработчик OnClose, который вполне может обратиться к переменной, указывающей на экземпляр TConnection, но которая была обнулена вызовом FreeandNil еще до вызова деструктора.

При чём тут вообще FreeAndNil, если вы его вызываете не вовремя? А если бы вы до вызова деструктора просто .Free вызвали - это было бы корректно что-ли?
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954981
misha mike,

Вызов из обработчика, по всем канонам ООП должен обращаться только к своему this(self) объекту. И никогда не обращаться на самого же себя, из глобальной переменной которая будет обнулена.


В данном случае Sender as TClass всегда указывает на текущий класс (Мы не говорим про случае доп классов, на класс)



Если соблюдать каноны, вы бы никогда себе не напридумывали проблем.

1) Ибо вы не можете создать несколько классов - разного типа, 1 класс всегда будет заменять другой, а вы получать пинка.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954982
misha mike
а FreeAndNil -- мгновенно AV



Пожалуйста, приведите пример кода с AV мы все хотим посмотреть, как вы будете создавать 2 класса из 1
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954995
Имеем
1) Класс 1 который ссылается на переменную глобальную класса 1
2) Класс 2 который создаются отдельно, и ссылается на переменную класса 1

Вопрос, что будет если Класс 1 не будет инициализирован хотя бы nil ?

И как итог - если Класс 2 будет освобождён, то он обратится к переменной класса 1.

И в конечном - увольнение с работы за дилетантство.

Не устраиваете на работу к себе misha mike, ибо любитель статичных костылей и незнания стандартных ООП применений (Класс должен быть унивирсальным)
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955014
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный, как хорошо, что ваше мнение никого не волнует.

Еще раз для всех собравшихся. Речь не идет об обращении к глобальной переменной класса прямо из обработчика. Речь идет о проекте на миллион строк, где черт ногу сломит, где в том числе работает и написанный пользователем код, где стек вызовов из обработчика имеет сотню уровней. И в этом коде не происходит обращения к мертвым объектам, но возможны обращения к глобальным переменным, потому что никто не тащил Sender через весь стек вызовов. Проект работает идеально, но простая замена Free + nil на FreeAndNil делает его неработоспособным и реального пути исправить это нет. Не протащить Sender каждого обработчика во все уголки, да еще так, чтобы пользовательский код в нужный момент обращался именно к нему, а не к переменной из global scope.

И именно об этом я написал в первом сообщении. Констатировал факт, что FreeAndNil <> Free + nil, и это иногда вылазит из неожиданных мест. В мире розовых пони FreeAndNil делает зашибись и избавляет от массы проблем, но реальность суровее.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955016
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
kealon(Ruslan)
объект пошёл на удаление - нефиг к нему лезть по глобальным переменным, только по эксклюзивному доступу (передавая указатель на себя) подписчикам

Это все правильно, но не всегда есть возможность заставить всех так делать. При этом имеем ситуацию, когда Free + nil работает идеально, ничего не течет, не крашится, и "математически" стабильно, а FreeAndNil -- мгновенно AV, которое без переписывания половины проекта не побороть.
проект явно в запущеном состоянии, с глубоким техническим долгом

для этого однозначно программист нужен, пробовали нанять?

поиск ошибок с порчей памяти куда дороже обходится чем AV
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955055
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А бездумное напихивание FreeAndNil - тоже заставляет задуматься о том, что программист не вполне уверен в своём коде и закладывается на AV как показатель бага, который не спорю, гораздо легче отыскать... И которого, возможно не могло возникнуть при правильной архитектуре))
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955060
misha mike,

Так зачем вы используете классы ? Вам не кажется что классы в вашем проекте - лишнее. Используется object объекты, или record

Вы не можете создать больше 1 класса, не нарушив логику работы двух экземпляров.


Ваш код - говнокод. В помойку.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955062
white_nigger
А бездумное напихивание FreeAndNil - тоже заставляет задуматься о том, что программист не вполне уверен в своём коде и закладывается на AV как показатель бага, который не спорю, гораздо легче отыскать...


Это не Не бездумное напихование, это гарант что программист не забудет обнулить ссылку на объект, который возможно по случайности где - то случайно начнёт использовать когда его не существует. И будет не понимать, почему у него беда


Написать free может каждый, а вот nil сделать - не каждый (Просто забыть)


white_nigger
И которого, возможно не могло возникнуть при правильной архитектуре))


Ну если программист самоучка начал писать свои велосипеды, и в будущем не может от них избавится... Это конечно беда. Ибо в них и вправду чёрт ногу сломишь, из за никого качества кода, и непродуманности

...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955063
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan), там не программист нужен, а волшебник. Точнее, команда волшебников.

А проект работает и продается за очень большие деньги. Просто однажды попробовали сделать по канонам и заменить кое-где Free на FreeAndNil, получили что получили, и откатили назад. Никто все равно не вложил бы кучу денег в переписывание того, что отлично работает.

Мне тот проект давно пофиг на самом деле, я лишь написал, что даже в сбалансированном (пусть и не по канонам писаном) приложении использование FreeAndNil может добавить головняка. Что хотел, сказал.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955066
misha mike,

Мне искренне жаль людей, которые покупают низко качественный продукт за большие деньги. (Возможно и переписать то там возможно за ночь с кружкой кофе не смотря в код, разумеется. Только ТЗ)
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955111
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger
А бездумное напихивание FreeAndNil - тоже заставляет задуматься о том, что программист не вполне уверен в своём коде и закладывается на AV как показатель бага, который не спорю, гораздо легче отыскать... И которого, возможно не могло возникнуть при правильной архитектуре))
расскажи, пожалуйста, обществу какая у вас правильная архитектура

самому то не смешно?
это неплохая защита и от последующих возможно косых изменений, что бы было видно когда забажили
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955119
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
самому то не смешно?
Что должно быть смешно? И что не понятно в моем посте?
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955121
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Товарищи, в таком русле ваш спор совершенно пустой.
Бездумное использование FreeAndNil - плохо, конечно.
Бездумное использование молотка тоже плохо, например.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955122
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам
Товарищи, в таком русле ваш спор совершенно пустой.
Бездумное использование FreeAndNil - плохо, конечно.
Бездумное использование молотка тоже плохо, например.
Полностью согласен. Было забавна потыкать палкой в холивар)) Больше не буду))
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955137
А я ещё раз повторю что, функция FreeAndNil нужна, когда нужно уничтожить объект, и ссылку на него. Что бы не обращаться к удалённому объекту, и не использовать не инициализированный объект.

Если при использование FreeAndNil вы видите ошибку AV, то вы плохой и ужасный программист. В том смысле, что вы заставляете работать класс с 1 экземпляром класса, который нельзя создать в другую переменную - изолировано.

Функция была придумана из выше сказанного, что бы не забывать дописать nil - переменной объекта, что бы в будущем не использовать объект, который уже был послан на уничтожение.

Деструктор, должен передавать в свои коллбэки ссылку на this(self) класса. А не ссылатся из коллбэка в глобальную область памяти.

Деструкту, и его методам - не нужно глобальная область переменных, которые ссылаются на свой же экземпляр.


Мы говорим о использование FreeAndNil в классовых объектах.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955139
Вот вам презик 100% защиты

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
function GetObjectClass(APointer: Pointer): TClass;
{$IFDEF MSWINDOWS}
var
  LMemInfo: TMemoryBasicInformation;

  { Checks whether the given address is a valid address for a VMT entry. }
  function IsValidVMTAddress(APAddress: Pointer): Boolean;
  begin
    { Do some basic pointer checks: Must be dword aligned and beyond 64K }
    if (UIntPtr(APAddress) > 65535) and (UIntPtr(APAddress) and 3 = 0) then
    begin
      { Do we need to recheck the virtual memory? }
      if (UIntPtr(LMemInfo.BaseAddress) > UIntPtr(APAddress)) or ((UIntPtr(LMemInfo.BaseAddress) + NativeUInt(LMemInfo.RegionSize)) < (UIntPtr(APAddress) + SizeOf(Pointer))) then
      begin
        { Get the VM status for the pointer }
        LMemInfo.RegionSize := 0;
        VirtualQuery(APAddress, LMemInfo, SizeOf(LMemInfo));
      end;
      { Check the readability of the memory address }
      Result := (NativeUInt(LMemInfo.RegionSize) >= SizeOf(Pointer)) and (LMemInfo.State = MEM_COMMIT) and
        (LMemInfo.Protect and (PAGE_READONLY or PAGE_READWRITE or PAGE_EXECUTE or PAGE_EXECUTE_READ or PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_WRITECOPY) <> 0) and (LMemInfo.Protect and PAGE_GUARD = 0);
    end
    else
      Result := False;
  end;

{ Returns true if AClassPointer points to a class VMT }
  function InternalIsValidClass(AClassPointer: Pointer; ADepth: Integer = 0): Boolean;
  var
    LParentClassSelfPointer: PPointer;
  begin
    { Check that the self pointer as well as parent class self pointer addresses
      are valid }
    if (ADepth < 1000) and IsValidVMTAddress(Pointer(PByte(AClassPointer) + vmtSelfPtr)) and IsValidVMTAddress(Pointer(PByte(AClassPointer) + vmtParent)) then
    begin
      { Get a pointer to the parent class' self pointer }
      LParentClassSelfPointer := PPointer(PByte(AClassPointer) + vmtParent)^;
      { Check that the self pointer as well as the parent class is valid }
      Result := (PPointer(PByte(AClassPointer) + vmtSelfPtr)^ = AClassPointer) and
        ((LParentClassSelfPointer = nil) or (IsValidVMTAddress(LParentClassSelfPointer) and InternalIsValidClass(LParentClassSelfPointer^, ADepth + 1)));
    end
    else
      Result := False;
  end;

begin
  { Get the class pointer from the (suspected) object }
  Result := TClass(PNativeUInt(APointer)^);
  { No VM info yet }
  LMemInfo.RegionSize := 0;
  { Check the block }
  if not InternalIsValidClass(Pointer(Result), 0) then
    Result := nil;
{$ELSE !MSWINDOWS}
begin
  { Not currently supported under Linux / OS X }
  Result := nil;
{$ENDIF MSWINDOWS}
end;

procedure FreeAndNil(var Obj); inline;
var
  Temp: TObject;
begin
  if GetObjectClass(Pointer(Obj)) <> nil then
  begin
    Temp := TObject(Obj);
    Pointer(Obj) := nil;
    Temp.Free;
  end;
end;



В нём совершенно нет ничего плохого в FreeAndNil. Вы туда не сможете передать ничего, что не имеет класса.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955142
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Няшик, спи уже.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955145
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger
А бездумное напихивание FreeAndNil - тоже заставляет задуматься о том, что программист не вполне уверен в своём коде и закладывается на AV как показатель бага, который не спорю, гораздо легче отыскать... И которого, возможно не могло возникнуть при правильной архитектуре))
авторКогда думаешь о том, где баг потенциально может возникнуть, а где нет, появляется опасная иллюзия, что ты держишь ситуацию под контролем, и предусмотрел все кейсы. Я работаю семь лет, ещё ни разу не было такого, чтобы я предусмотрел все кейсы. Потому что это частный случай задачи коммивояжера — ты НИКОГДА не можешь предусмотреть все кейсы. Ты даже самые распространенные и вероятные рассмотреть не можешь. Когда, кто и в какой ситуации напишет код с критичным багом, в каком модуле и как он это сделает — ты, блин, понятия не имеешь. Все, что ты можешь сделать, это уменьшить шансы на появление бага. Вот и уменьшай, тебе за это платят бешеные деньги. https://habr.com/ru/post/500926/
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955146
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955150


Ну не знаю, не знаю.. Что плохого в том, что компилятор за тебя решает как сравнивать типы разного характера 35 = "35str"

Тем более, я более чем уверен что написанное на c++ это делает как

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
bool InlineCmpNode(Nodes Node, byte TypeVar) {
	void *ArrCmpType[3] = {&&CmpInt, &&CmpDouble, &&CmpString};

	goto *ArrCmpType[TypeVar];

	auto Var1 = Node[0];
	auto Var2 = Node[1];

	// Реализация перезагрузки для сравнения с Int и String к примеру (overload in delphi)

	CmpInt:
	 return InlineCmpInt(Var1, Var2);
	 
	CmpDouble:
	 return InlineCmpDouble(Var1, Var2);
	 
	CmpString:
	 return InlineCmpString(Var1, Var2);
}



Данный код, укороченный рабочий прототип одного закрытого проекта.

В данном случае, goto работает никак switch стандартный. А именно jmp OFFSET

Код: sql
1.
2.
3.
4.
5.
6.
7.
        mov     eax, OFFSET FLAT:.L9
        movsx   rsi, esi
        mov     QWORD PTR [rsp-24], OFFSET FLAT:.L11
        movq    xmm0, rax
        movhps  xmm0, QWORD PTR .LC1[rip]
        movaps  XMMWORD PTR [rsp-40], xmm0
        jmp     [QWORD PTR [rsp-40+rsi*8]]



Это чистая адресация, по сравнению с тем, что мы можем видеть при switch
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
        mov     r8d, DWORD PTR [rdi]
        mov     r9d, DWORD PTR [rdi+4]
        cmp     esi, 64
        je      .L13
        cmp     esi, 512
        mov     edi, r8d
        mov     esi, r9d
        jne     .L14
        jmp     InlineCmpInt(auto, auto)



На самом деле сравниваемых типов около 16, это ресурсы \ структуры и прочее. Я оставил только основное, и switch генерирует слишком много cmp что в два раза медленнее работает если сравниваемый объект хранится в конце списка.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39955151
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный


Ну не знаю, не знаю.. Что плохого


...
Рейтинг: 0 / 0
25 сообщений из 226, страница 7 из 10
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Улучшил FreeAndNil. Можете не благодарить.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]