Конференция "Прочее" » Вопрос по уничтожению объектов
 
  • 123-ий © (09.02.09 07:42) [0]
    Тут как бы надо знать устройство дельфового менеджера памяти на более высоком уровне, чем его знаю я. Поэтому спрошу в сюда.
    вот код:

    function GetSomeList: TStringList;
    begin
     Result := TStringList.Create;
     // Заполняю стринглист
    end;


    далее я вызываю данную функцию, например

    SomeListBox.Items := GetSomeList;


    теперь результат работы функции GetSomeList надо как-то уничтожить.
    Если сделать
    GetSomeList.Free

    - функция выполняется два раза, а это не оптимально, да и порой неудобно. Каким образом лучше реализовать? То есть мне просто надо сделать функцию, возвращающую стринглист и чтобы без утечки памяти.
  • MBo © (09.02.09 07:50) [1]
    сделай процедуру, которой передаешь созданный TStringList, потом его уничтожаешь, когда нужно.
  • Palladin © (09.02.09 08:04) [2]
    Procedure FillStringList(p_theSL:TStringList);
    Begin
     .. заполняем
    End;

    Var
     theSL:TStringList;
    Begin
     theSL:=TStringList;
     Try
      FillStringList(theSL);
      ...
     Finally
      theSL.Free;
     End;
    End;



    это - правильно
  • Palladin © (09.02.09 08:06) [3]
    зачем создавать TStringList для св-ва TStrings если оно уже создано и используется в объекте

    Procedure FillStringList(p_theSL:TStrings);
    Begin
    .. заполняем
    End;

    FillStringList(SomeListBox.Items);
  • korneley © (09.02.09 08:13) [4]

    > Palladin ©   (09.02.09 08:04) [2]
    > theSL:=TStringList;

    theSL:=TStringList.Create;

    Я не смеюсь, мало ли, чего недопонял :)
  • Palladin © (09.02.09 08:13) [5]
    :) никто не застрахован от описек и недописек :)
  • Skyle © (09.02.09 08:22) [6]

    > korneley ©   (09.02.09 08:13) [4]

    Это не чистый дельфи, это Palladin Delphi Extension ®
  • 123-ий © (09.02.09 09:27) [7]

    > Palladin ©   (09.02.09 08:04) [2]

    идею понял. так и сделаю ибо проще. спасибо.
    а все таки интересно, как ведет себя менеджер памяти. Вот когда я делаю так:
    SomeListBox.Items := GetSomeList;
    в SomeListBox.Items передается указатель на стринглист созданный функцией GetSomeList. Если например сделать так:

    var
     TempList: TStringList;
    begin
     TempList := GetSomeList;
     try
       SomeListBox.Items := TempList;
     finally
       TempList.Free;
     end;
    end;


    если в TempList передается указатель на стринглист, созданный функцией GetSomeList, то при выполнении строки TempList.Free этот самый стринглист должен умереть. Я прав?
  • Сергей М. © (09.02.09 09:30) [8]

    > 123-ий ©   (09.02.09 09:27) [7]


    > Я прав?


    Угу.
  • Palladin © (09.02.09 09:41) [9]

    > 123-ий ©   (09.02.09 09:27) [7]

    Абсолютно, но функций создающих и возвращающих объект какого то класса, нужно по возможности избегать. Все дело в том, что в процессе создания и/или инициализации этого объекта может произойти исключение и, в следствии этого утечка памяти.

    Например

    Function CreateMyObj:TMyClass;
    Begin
     Result:=TMyClass.Create;
     Result.Prop1:=Value1; // предположим, здесь возникает исключение
    End;

    Var
    obj:TMyClass;
    Begin
     obj:=CreateMyObj;
     Try
      ...
     Finally
      obj.Free; // бесполезно, объект создан, но исключение произошло не в Try/Finally, а во время выполнения функции, соответственно после исключения при назначении свойству значения, ссылка на созданный объект теряется
     End;
    End;

  • KSergey © (09.02.09 09:42) [10]
    > Palladin ©   (09.02.09 08:04) [2]
    > Procedure FillStringList(p_theSL:TStringList);
    > Begin
    >  .. заполняем
    > End;

    Тогда даже лучше

    Procedure FillStringList(p_theSL:TStrings);



    Тогда туда можно будет передавать в том числе и Items от SomeListBox и не придется создавать временный, а потом из него копировать.
  • Palladin © (09.02.09 09:43) [11]
    Именно в [3], по этому поводу, я и исправился, более внимательней прочитав вопрос )
  • KSergey © (09.02.09 09:44) [12]
    > Palladin ©   (09.02.09 09:43) [11]

    а, точно, не заметил, сорри.
  • KSergey © (09.02.09 09:45) [13]
    А почему вопрос задан в потрепаться, а не в тематической?? вполне себе тематический вопрос, по-моему.
  • Anatoly Podgoretsky © (09.02.09 09:51) [14]
    > Palladin  (09.02.2009 9:41:09)  [9]

    Это можно легко исправить, немного переделав функцию, но смысла нет.
  • 123-ий © (09.02.09 10:03) [15]

    > KSergey ©   (09.02.09 09:45) [13]

    на всякий случай. туда предпочитаю не лазить почему то. :)

    > Anatoly Podgoretsky ©   (09.02.09 09:51) [14]

    смысла то нет, а все тки расскажите. =) интересно
  • test © (09.02.09 10:15) [16]
    KSergey ©   (09.02.09 09:45) [13]
    Тут мастеров больше ))
  • KSergey © (09.02.09 10:24) [17]
    > 123-ий ©   (09.02.09 10:03) [15]
    > смысла то нет, а все тки расскажите. =) интересно

    А  самому подумать? как подсказка - try/except
  • Rouse_ © (09.02.09 10:41) [18]
    А я вот немного не пойму, пример в [0] был тестовый или взятый из "реальной жизни"? Просто зачем создавать промежуточный TStringList если он уже создан в SomeListBox? Может проще брать его оттуда и использовать? Зачем лишние затраты на создание класса и вызов Assign-а при присвоении?
  • {RASkov} © (09.02.09 10:59) [19]
    > [0] 123-ий ©   (09.02.09 07:42)
    > GetSomeList.Free - функция выполняется два раза, а это не оптимально, да и порой неудобно.

    Более того.... Неправильно, ибо память, выделенная в первом вызове, так и утекет в никуда....
 
Конференция "Прочее" » Вопрос по уничтожению объектов
Есть новые Нет новых   [134454   +43][b:0][p:0.002]