Конференция "Прочее" » FreeAndNil
 
  • dmk © (11.12.18 20:54) [40]
    >sniknik ©   (11.12.18 20:40) [38]
    Так только для переменной подходит. Через PObject еще из массива освобождать можно.
    Где AVar - указатель на ячейку массива, а AVar^ доступ к переменной в ячейке, т.к. в ячейке хранится ссылка на другую переменную. Запутано конечно, но работает норм.
    В упрощенном виде:
    1. Доступ к переменной - PVar(AVar)^.
    2. Доступ к ячейке массива в которой хранятся ссылки на переменные - PObject(AVar^)^.
  • dmk © (11.12.18 20:56) [41]
    >Да проще свой препроцессор написать.
    Уже хочется свой компилятор если чесно. Куча ограничений кругом.
  • dmk © (11.12.18 20:57) [42]
    >Embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут.
    Они вам продадут эту фичу лет через 5 в версии 11.4. Это же маркетинг.
  • ухты © (11.12.18 22:38) [43]
    вы как переменные в ячйку запихали? ))
  • Тимохов Дима © (11.12.18 22:51) [44]
    мое имхо, что можно делать, что хочешь, лишь бы тебе было понятно и полезно.
    domain specific language, ёлки.
  • dmk © (11.12.18 23:04) [45]
    >вы как переменные в ячйку запихали? ))
    Для этого надо 2 высших иметь. У вас есть 2 высших?
  • ухты © (11.12.18 23:08) [46]
    тут 2 мало, тут надо щтук пять а лучше шесь, но у меня семь, так что все в порядке
  • dmk © (11.12.18 23:12) [47]
    >ухты
    А вообще вам сюда: http://butanti.forum24.ru/
    а здесь Обжект Паскаль обсуждают.
  • ухты © (11.12.18 23:18) [48]
    вы не обсуждаете а лепите. что то издалека напоминающее что то типа турбо паскаль ))
    со всвоими велосипедами в виде эти фри[энднил], ну и венцом из переменных в ячейках.
    и можно тольео повторить -

    > дичь какая-то
  • Германн © (12.12.18 02:03) [49]

    >  Sha ©   (11.12.18 09:24) [23]
    >
    > > Германн ©   (11.12.18 02:49) [22]
    >
    > чем-то это мне напоминает борьбу с GOTO )

    Почему только напоминает?
    Это та же самая борьба только на другом фронте. :)
  • Германн © (12.12.18 02:21) [50]

    > Sha ©   (11.12.18 09:24) [23]
    >
    > > Германн ©   (11.12.18 02:49) [22]
    >
    > чем-то это мне напоминает борьбу с GOTO )

    Ведь использование GOTO подразумевает использование Label, которые можно ставить в коде что в паскалевской, что в Дельфийской программе практически где угодно (возможно не везде, но я это не проверял).
    И IDE/Компилятор не могут уверенно указать на принципиальную ошибку алгоритма/программы.
    Т.о. вся ответственность за использование такого полностью ложится на его автора. Но готов ли автор её принять?
  • Sha © (12.12.18 10:02) [51]
    > Германн ©   (12.12.18 02:21) [50]

    И GOTO, и FreeAndNil обычно не требуются программисту.

    Но в тех редких случаях, когда их применение действительно имеет смысл,
    они способны существенно упростить алгоритм или повысить скорость.
  • sniknik © (12.12.18 11:41) [52]
    >>sniknik ©   (11.12.18 20:40) [38]
    > Так только для переменной подходит. Через PObject еще из массива освобождать можно.
    да, я понял, у тебя в объекте указатель на себя же, на внешнюю переменную с собой(которая тоже указатель). по нему "обниляеш" именно внешнюю.
    поначалу сбило то, что ты в примере его во Free переменной передаешь, а не берешь из внутренних переменных.

    вообще, "претензия" к такому подходу только в том что это громоздко и сложно для понимания (самому через пару лет поменять понадобится...).

    лучше бы как то поменять логику, обойтись например без внешней вообще, работать со спискам объектов, в котором их уничтожение уже реализовано (приснопамятный сборщик мусора... ), ну вот, тут адрес внешний внутрь передается, но смысла в этом не вижу, если уж нужна для работы используй и бросай без Free, список потом сам позаботится.
    type
     TMyObject = class(TObject)
       Obj: TMyObject;
       destructor Destroy; override;
     end;

    destructor TMyObject.Destroy;
    begin
     inherited;
     Form1.Edit1.Text:= '!!!!!!'
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
     i: integer;
     ObL: TObjectList;
     pO: TMyObject;
    begin
     ObL:= TObjectList.Create;
     try
       ObL.Add(TObjectList.Create);
       ObL.Add(TObject.Create);
       i := ObL.Add(TMyObject.Create);
       pO:= TMyObject(ObL.Items[i]);
       pO.Obj:= @pO;
     finally
       ObL.Free;
     end;
    end;

  • dmk © (12.12.18 12:07) [53]
    >вообще, "претензия" к такому подходу только в том
    >что это громоздко и сложно для понимания
    Так я без наставлений в народ вышел. Просто спросил, а меня уже запинали.
    У меня 3D-эшечка. 3D-объекты вещь комплексная и создаются у меня в разных местах и разными методами. Модифицируются также в разных местах и даже в разных модулях. Загружаются в массивы или переменные. Вот например, система частиц - это же массив созданных процедурно или загруженных из файла объектов. У них даже классы обработки разные. Только общий предок TZObject. Частицы находятся в одном массиве. Объекты взаимодействия в другом или вообще в отдельной переменной. У меня и так перерасход памяти жуткий идет, а вы мне предлагаете еще один массив с T-классом сделать. Двойное существование объекта в общем то не нужно. Поэтому я и придумал массив ссылок (сцена). Может как то иначе этот массив можно представить?

    У меня так сделано:
    type
     PZScene = ^TZScene;
     TZScene = class
     private
       FObjects: array of PZObject;
       FNumObjects: Integer;
       FSceneStatistic: TSceneStatistic;
       procedure SetObject(Index: Integer; Value: PZObject); inline;
       function GetObject(Index: Integer): PZObject; inline;
     public
       constructor Create;
       destructor Destroy; override;
       procedure AddObject(Value: PZObject);
       procedure ChangeTarget(ATarget: PBitmap64);
       procedure DeleteObject(Value: PZObject);
       procedure DestroyObjects;
       procedure DrawObjects;
       function GetMaxObjectsDepth: Single;
       function GetDepth: Single;
       procedure InverseDraw;
       function LowIndex: Integer; inline;
       function HighIndex: Integer; inline;
       function NumJoins: Integer;
       function NumPoints: Integer;
       function NumTriangles: Integer;
       function ObjectExist(Value: PZObject): Boolean; inline;
       function ObjectIndex(Value: PZObject): Integer; inline;
       procedure Reset;
       procedure SetFill(Value: Boolean);
       procedure SetStroke(Value: Boolean);
       procedure SetOpacity(Value: Single);
       procedure ScaleObject(Value: PZObject; F: Single);
       procedure ScaleObjects(Value: Single);
       procedure SetCheckerColors(Args: array of TColor32);
       procedure SetHSVColors(AOrient: TPlaneType);
       procedure SetObjectFirst(Value: PZObject);
       procedure SetRandomColors;
       procedure UpdateStatistic;
       //---
       property Objects[Index: Integer]: PZObject read GetObject write SetObject;
       property NumObjects: Integer read FNumObjects;
       property Statistic: TSceneStatistic read FSceneStatistic;
     end;

    procedure TZScene.AddObject(Value: PZObject);
    begin
     if (Value^ <> nil) then
     begin
       if not ObjectExist(Value) then
       begin
         Inc(FNumObjects);
         SetLength(FObjects, FNumObjects);
         FObjects[High(FObjects)] := Value;
       end;
     end;
    end;

    procedure TZScene.DeleteObject(Value: PZObject);
    var
     i, k: Integer;
     Found: Boolean;

    begin
     if (FNumObjects > 0) and (Value <> nil) then
     begin
       Found := False;
       k := LowIndex;

       for i := LowIndex to HighIndex do
       begin
         if FObjects[i] = Value then
         begin
           FreeAndNil(@Value^);
           Found := True;
           Continue;
         end
         else //Пропустим удаленный объект
         begin
           FObjects[k] := FObjects[i];
           Inc(k);
         end;
       end;//for

       FNumObjects := k;
       SetLength(FObjects, FNumObjects);

       //Если не найден, то удаляем объект вне сцены
       if (not Found) then FreeAndNil(@Value^);
     end;
    end;

    procedure TZScene.DestroyObjects;
    var
     i: Integer;

    begin
     if (FNumObjects > 0) then
     begin
       for i := Low(FObjects) to High(FObjects) do
       begin
         FObjects[i].Free(@FObjects[i]^);
       end;

       SetLength(FObjects, 0);
       FNumObjects := 0;
     end;
    end;


    Добавляются объекты в сцену так:
     //Удаляем старый объект
     Scene.DeleteObject(@gObject);

     //Создаем и загружаем файл
     LoadObj(OpenMeshDialog.FileName, RT, @ZCam, @gObject);

     if gObject.Correct then
     begin
       Scene.AddObject(@gObject);
       Scene.SetObjectFirst(@gObject);
     end;


    Потом сцена удаляется:
    procedure TRenderForm.FreeScene;
    begin
     if bSceneActive then
     begin
       //Массив ссылок на Z-Объекты
       Scene.DestroyObjects;

       //Объекты вне массива
       FreeAndNil(@gVarious);
       FreeAndNil(@gObject);
       FreeAndNil(@gGrid);
       FreeAndNil(@gFrustum);

       //Кнопка загрузки
       FLoadBtn.Visible := False;
       FLoadBtn.Enable := False;

       //Флаг использования 3D
       bSceneActive := false;
     end;
    end;

    Но мой вариант рабочий и вроде уже привык.
    Можно как то проще сделать? Буду рад услышать хорошие советы.
  • dmk © (12.12.18 12:15) [54]
    Мне nil понадобился, чтобы точно узнавать — инициализирован объект или нет.
    Если nil - то создаем в этой переменной или ячейке в массиве. У меня объекты динамически создаются/удаляются и какая переменная освободится заранее не известно.
    Вот здесь видно поведение объектов:
    https://yadi.sk/i/tU7G3tfHrl4hBQ
  • sniknik © (12.12.18 16:13) [55]
    > Можно как то проще сделать?
    имхо конечно, но я как раз проще и посоветовал, работать со списком, стандартным. а не с массивом, и своим "велосипедом" по его обработке...
    ну, совсем без велосипеда не обойтись, но вот наследуй твой TZScene от TObjectList и у тебя сразу появятся стандартные методы по добавлению/удалению объектов, и "дестроить" их самому/следить за этим/за массивом не нужно будет, и т.д. много преимуществ/упрощений на мой взгляд.
    не, я конечно не совсем в теме, что у тебя там, со стороны не видно, вот к примеру зачем в 2-х местах ссылки? бери всегда из списка да и все. копию просто игнорь, в следующий раз если понадобится снова из списка, а nil-ов в нем попросту не будет, - стал не нужен объект, удалил из списка, а он уже сам его освободит... удобно.
  • dmk © (12.12.18 17:10) [56]
    >TObjectList
    Тут есть оговорка. VCL не используется. Почти чистый WinApi. Вплоть до своего менеджера памяти.
  • Владислав © (12.12.18 19:50) [57]
    Какой феерический трындец.

    > TObjectList
    > Тут есть оговорка. VCL не используется.

    Можно посмотреть, как он реализован, не слишком сложная задача.

    После просмотра этого:

    >type
    >  PZScene = ^TZScene;
    >  TZScene = class

    и этого:

    >Вплоть до своего менеджера памяти.

    у меня когнитивный диссонанс возникает.

    Не дай бог такое приснится.
  • virex(home) © (12.12.18 20:24) [58]
    > pavia ©   (11.12.18 20:52) [39]
    >
    >
    > > прикольно, трупы сами себе могилу роют.
    >
    > в нормальных языках это давно так реализовано.
    >
    >
    > > возможно ли сделать так, чтобы объект при уничтожении сам
    > > себе присваивал nil?
    > > или надо freeandnil использовать?
    >
    > нельзя.
    > embarcodere уже который год тянут кота за яйца, но автосборку мусора сделать не могут.
    > да проще свой препроцессор написать.
    нормальный язык это где gc находит трупы и закапывает?
  • Германн © (13.12.18 01:59) [59]

    > Sha ©   (12.12.18 10:02) [51]
    >
    > > Германн ©   (12.12.18 02:21) [50]
    >
    > И GOTO, и FreeAndNil обычно не требуются программисту.
    >
    > Но в тех редких случаях, когда их применение действительно
    > имеет смысл,
    > они способны существенно упростить алгоритм или повысить
    > скорость.

    Вот с этим я как раз и не спорил. Более того. У меня был случай, когда GOTO давал гораздо более понятный при просмотре/анализе/отладке код.
    А вот FreeAndNil никогда. Возможно потому, что у меня не достаточно было опыта.
Есть новые Нет новых   [134427   +34][b:0][p:0.001]