Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.09.10;
Скачать: [xml.tar.bz2];

Вниз

Освободить память после 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.037 c
2-1156259071
Sele
2006-08-22 19:04
2006.09.10
tcpclient + server


15-1155037865
Lexiy
2006-08-08 15:51
2006.09.10
Прием на работу


2-1155856952
SerJaNT
2006-08-18 03:22
2006.09.10
Handle активного окна


2-1156046178
Vasiliy
2006-08-20 07:56
2006.09.10
Как осуществить прокрутку в ScrollBox?


1-1154280131
Lordalexander
2006-07-30 21:22
2006.09.10
Прозрачный Label





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский