![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Освободить память после function MyFunction:TMemoryStream; [D7, 2000]
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