Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.10;
Скачать: CL | DM;

Вниз

Освободить память после function MyFunction:TMemoryStream;   Найти похожие ветки 

 
Shaman_ ©   (2006-08-16 16:20) [0]

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

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

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


 
Desdechado ©   (2006-08-16 16:21) [1]

x:=MyFunction;
x.Free;


 
Сергей М. ©   (2006-08-16 16:22) [2]

Stream := MyFunction;
try
...
finally
Stream.Free;
end;


 
Джо ©   (2006-08-16 16:22) [3]

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


 
Джо ©   (2006-08-16 16:23) [4]

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

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


 
Джо ©   (2006-08-16 16:23) [5]

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

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


 
begin...end ©   (2006-08-16 16:25) [6]

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

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


 
Shaman_ ©   (2006-08-16 16:47) [7]

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

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 как параметр в функцию.

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


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


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


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


 
begin...end ©   (2006-08-16 16:52) [9]

Мдя...


 
Shaman_ ©   (2006-08-16 16:56) [10]

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


 
begin...end ©   (2006-08-16 16:58) [11]

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

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


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

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


 
Desdechado ©   (2006-08-16 17:05) [13]

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


 
begin...end ©   (2006-08-16 17:06) [14]

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

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

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

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

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

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

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

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

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


 
DiamondShark ©   (2006-08-16 17:07) [15]

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


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

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Мб


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

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

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


 
DevilDevil ©   (2006-08-16 17:24) [18]

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;


 
Shaman_ ©   (2006-08-16 17:36) [19]


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


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


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

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


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

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

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

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

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


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


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

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


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

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



Страницы: 1 вся ветка

Текущий архив: 2006.09.10;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.029 c
3-1152175448
WhiteBarin
2006-07-06 12:44
2006.09.10
Как получить скрипт вставляемой запись в БД через FIB+ ?


2-1156263776
GunGarry
2006-08-22 20:22
2006.09.10
Заблокировать файл папку


2-1155803302
Андрей123
2006-08-17 12:28
2006.09.10
Помогите!!! Как изменить запятую на точку


2-1155817627
Anonimus11
2006-08-17 16:27
2006.09.10
База данных


2-1156348469
NikIta88
2006-08-23 19:54
2006.09.10
Не убивается таймер после цикла сообщений