Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Освободить память после function MyFunction:TMemoryStream; [D7, 2000]


Страницы:   1 2

Shaman_ ©   (2006-08-16 16:20:00) 

Функция должна вовзращать результат в виде класса:

function MyFunction:TMemoryStream;
begin
Result := TMemoryStream.Create;
...
end;

Торможу, не могу освободить память, на создание экземпляра класса, после вызова функции.
Подскажите как это правильно делать?


Джо   (2006-08-17 00:42:00) [1]

А если уж делать, то к выбору названия функции нужно подойти с особым вниманием. Чтобы из него четко было ясно, что функция создает объект. Например, против такого
function CreateStreamFromBytes (Bytes: TByteArray): TStream;
не слишком много доводов можно привести :) Не особенно отличается от вызова конструктора и визуально все сразу ясно. Похоже на фабричные методы/функции.


Kolan   (2006-08-17 00:26:00) [2]


> Почему? (не спорю, но хочу понять)

По тому, что когда создал в одном месте а удалять надо в другом, то можно и забыть удалить...


Vovan#1   (2006-08-17 00:21:00) [3]

Джо ©   (16.08.06 16:23) [4]

> Подскажите как это правильно делать?

>Лучше вообще так не делать а делать, а передавать Stream как параметр в >функцию.

Почему? (не спорю, но хочу понять)


Shaman_   (2006-08-16 17:36:00) [4]


Память это конечно освободит только вместе с освобожденной памятью заодно обнулит результат функции


begin...end ©   (16.08.06 17:06) [14]
Это не обнулит результат функции.


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

Всем спасибо!


DevilDevil   (2006-08-16 17:24:00) [5]

procedure TForm1.Button1Click(Sender: TObject);
var
tmp, Buf: TMemoryStream;
i: integer;
begin
tmp := TMemoryStream.Create;
for i := 0 to 1000000 do
begin
Buf := MyFunction;
tmp.LoadFromStream(Buf);
Buf.Free;
end;
tmp.Free;
end;


begin...end   (2006-08-16 17:13:00) [6]

> Shaman_ ©   (16.08.06 17:12) [16]

На каждом проходе цикла у Вас создаётся два объекта, а освобождается только один из них.


Shaman_   (2006-08-16 17:12:00) [7]

Desdechado ©   (16.08.06 17:05) [13]
Пардон, на access violation не вылетаем, но и память не освобождает
Вот попробуй выполнить:

function MyFunction:TMemoryStream;
begin
Result := TMemoryStream.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
tmp: TMemoryStream;
i: integer;
begin
tmp := TMemoryStream.Create;
for i := 0 to 1000000 do
begin
 tmp.LoadFromStream(MyFunction);
 MyFunction.Free;
end;
tmp.Free;
end;

Сожрет ~20Мб


DiamondShark   (2006-08-16 17:07:00) [8]

Оставьте его. Он просто издевается.


begin...end   (2006-08-16 17:06:00) [9]

> Shaman_ ©   (16.08.06 16:47) [7]

> вылетим на access violation

Проверить -- не судьба?

> Память это конечно освободит только вместе с освобожденной
> памятью заодно обнулит результат функции

Это не обнулит результат функции.

> Этот вариант не освобождает память

Этот вариант освобождает память, если в процессе работы функции после создания экземпляра TMemoryStream возникнет исключение. Мой ответ был дополнением к [1]-[3], это был совет, относящийся к оформлению кода функции, если она создаёт объект и возвращает ссылку на него.

> Shaman_ ©   (16.08.06 17:00) [12]

Код [2] -- это код, расположенный за пределами функции.


Desdechado   (2006-08-16 17:05:00) [10]

> x:=MyFunction;
> x.Free;
> вылетим на access violation
Это чего вдруг?


Shaman_   (2006-08-16 17:00:00) [11]

До выхода из функции


begin...end   (2006-08-16 16:58:00) [12]

> Shaman_ ©   (16.08.06 16:56) [10]

До какого выхода? Откуда?


Shaman_   (2006-08-16 16:56:00) [13]

Книжки бы тебе почитать, барин)
Лучше бы по существу чего написал...
Каким боком функция вернет значение если возвращаемый класс уничтожается еще до выхода?


begin...end   (2006-08-16 16:52:00) [14]

Мдя...


Сергей М.   (2006-08-16 16:51:00) [15]


> Shaman_ ©   (16.08.06 16:47) [7]
>
> Stream := MyFunction;
> try
> ...
> finally
> Stream.Free;
> end;
>
> Память это конечно освободит только вместе с освобожденной
> памятью заодно обнулит результат функции


Книжки бы тебе почитать, барин)


Shaman_   (2006-08-16 16:47:00) [16]

В итоге все варианты по освобождению памяти не рабочие:

Desdechado ©   (16.08.06 16:21) [1]

x:=MyFunction;
x.Free;

вылетим на access violation


Сергей М. ©   (16.08.06 16:22) [2]
Stream := MyFunction;
try
...
finally
Stream.Free;
end;

Память это конечно освободит только вместе с освобожденной памятью заодно обнулит результат функции :)

Джо ©   (16.08.06 16:22) [3]
тоже самое что [2]


begin...end ©   (16.08.06 16:25) [6]

А функцию написать так:

Result := TMemoryStream.Create;
try
...
except
Result.Free;
raise
end;

Этот вариант не освобождает память
Вот попробуй выполнить

function MyFunction:TMemoryStream;
begin
try
 Result := TMemoryStream.Create;
except
 Result.Free;
 Raise;
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
tmp: TMemoryStream;
begin
tmp := TMemoryStream.Create;
 for i := 0 to 1000000 do
 begin
  tmp.LoadFromStream(MyFunction);
 end;
tmp.Free;
end;

И проверь сколько памяти было израсходованно до нажатия на Button и сколько после- вылетит 25 Мб


Джо ©   (16.08.06 16:23) [4]
Лучше вообще так не делать а делать, а передавать Stream как параметр в функцию.

Понимаю что можно и так делать, но вопрос всеже в другом :)


begin...end   (2006-08-16 16:25:00) [17]

А функцию написать так:

Result := TMemoryStream.Create;
try
 ...
except
 Result.Free;
 raise
end;


Джо   (2006-08-16 16:23:00) [18]

> [4] Джо ©   (16.08.06 16:23)
> > Подскажите как это правильно делать?
>
> Лучше вообще так не делать а делать, а передавать Stream
> как параметр в функцию.

+ создавать его ДО вызова функции.


Джо   (2006-08-16 16:23:00) [19]

> Подскажите как это правильно делать?

Лучше вообще так не делать а делать, а передавать Stream как параметр в функцию.


Джо   (2006-08-16 16:22:00) [20]

var
 AStream: TMemoryStream;
begin
 AStream := MyFunction;
 try
   ///
   ///
   ///
 finally
   AStream.Free
 end;
end


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо