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

Вниз

Дин.массив на выходе ф-ции и утечка   Найти похожие ветки 

 
GanibalLector ©   (2007-01-10 23:26) [0]

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

function Get(...): Pointer;
var
V: array of sometype;
begin
SetLength(V, xxx);
...
Inc(PLongint(Longword(V) - 8)^);
Result := V;
end


Вопрос : как, собственно, избавится от данной проблемы ?
Заранее спасибо.


 
GanibalLector ©   (2007-01-10 23:28) [1]

Весь код :

type
TMyData = packed record
 Mode:Byte;
 Data:array of String[$FF];
end;
PMyData = ^TMyData;

var
 Form1: TForm1;

implementation

{$R *.dfm}

function Potok(Param:PMyData):DWord;
 var I:Integer;
begin
 // работаем с массивом ...

 Param.Data:=nil; // освобождение дин.массива
 Dispose(Param);
 Result:=0;
end;

function GetData:Pointer;
 var S:array of String[$FF];
     I:Integer;
 const Count = 150;
begin
 SetLength(S,Count);
 for I:=0 to Count-1 do
  S[I]:="Test"+IntToStr(I);
 Inc(PLongint(LongWord(S) - 8)^);
 Result := S;
end;

procedure TForm1.Button1Click(Sender: TObject);
 var ThreadID:DWord;
     Obj:PMyData;
begin
 New(Obj);
 Obj^.Mode:=$A;

 // так работает БЕЗ УТЕЧЕК

 SetLength(Obj^.Data,3);
 Obj^.Data[0]:="Test1";
 Obj^.Data[1]:="Test2";
 Obj^.Data[2]:="Test3";

 // а так С УТЕЧКОЙ

 //Obj^.Data:=GetData;

 CloseHandle(BeginThread(nil,0,@Potok,Obj,0,ThreadID));
end;

end.



 
Игорь Шевченко ©   (2007-01-10 23:35) [2]


> Inc(PLongint(Longword(V) - 8)^);


А это зачем ?


 
Джо ©   (2007-01-10 23:37) [3]

Inc(PLongint(Longword(V) - 8)^);
Вероятно, счетчик ссылок увеличивается. Правда, зачем, действительно, непонятно.


 
Anatoly Podgoretsky ©   (2007-01-10 23:38) [4]

> GanibalLector  (10.01.2007 23:28:01)  [1]

Массив размещен на стеке и прекращает свое существование при выходе из процедуры.


 
tesseract ©   (2007-01-10 23:41) [5]

Так попробуй, указатели лучше в функцию передавать.


type MyType:=array of string[$FF];
procedure GetData(var S:MyType):
var
 I:Integer;
const Count = 150;
begin
SetLength(S,Count);
for I:=0 to Count-1 do
 S[I]:="Test"+IntToStr(I);
Inc(PLongint(LongWord(S) - 8)^);
end;


 
Джо ©   (2007-01-10 23:41) [6]

Я не понимаю, почему бы не сделать так:

function Get: TArray;
begin
 SetLength(Result,N);
 Result[i] := ....
 ...
end;


 
tesseract ©   (2007-01-10 23:42) [7]


> Anatoly Podgoretsky ©   (10.01.07 23:38) [4]


опередил :-)


 
Loginov Dmitry ©   (2007-01-10 23:45) [8]

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


А что-то иное предполагалось?


 
GanibalLector ©   (2007-01-10 23:57) [9]

2 Джо ©   (10.01.07 23:41) [6]
Не совсем понял что имелось ввиду.  TArray это что ???


 
Джо ©   (2007-01-11 00:16) [10]

> [9] GanibalLector ©   (10.01.07 23:57)
> 2 Джо ©   (10.01.07 23:41) [6]
> Не совсем понял что имелось ввиду.  TArray это что ???

array of sometype;


 
GanibalLector ©   (2007-01-11 00:25) [11]

2 Джо ©   (11.01.07 00:16) [10]
А оно так не компилируется. Я про array of sometype.
Например, function Get: array of String[$FF];


 
Джо ©   (2007-01-11 00:39) [12]

> Например, function Get: array of String[$FF];

Делай так:

type
 TArray = array of sometype;

function Get: TArray;


 
GanibalLector ©   (2007-01-11 01:11) [13]

2 Джо ©   (11.01.07 00:39) [12]
Сделал.

Теперь  :

function Get: TArray;
begin
SetLength(Result,2);
Result[0] := "test1";
Result[1] := "test2";
end;

procedure TForm1.Button1Click(Sender: TObject);
 var ThreadID:DWord;
     Obj:PMyData;
begin
 New(Obj);
 Obj^.Mode:=$A;
 Obj^.Data:=Get; // Incompatible types
 CloseHandle(BeginThread(nil,0,@Potok,Obj,0,ThreadID));
end;


 
ors_archangel ©   (2007-01-11 01:25) [14]

obj.data должно быть тоже типа TArray


 
GanibalLector ©   (2007-01-11 01:30) [15]

Опс...действительно ;) пардон.
Всем спасибо!


 
oxffff ©   (2007-01-11 08:56) [16]


> Anatoly Podgoretsky ©   (10.01.07 23:38) [4]
> > GanibalLector  (10.01.2007 23:28:01)  [1]
>
> Массив размещен на стеке и прекращает свое существование
> при выходе из процедуры.


Это не верно!!!
Динимические массивы не размещены на стеке!!!

Вот пример. Утечек нет.

mytype=array of string[255];

function getData:pointer;
var a:mytype;
begin
setlength(a,10);
Inc(PLongint(Longword(a) - 8)^);
result:=a;
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:mytype;
begin
pointer(a):=getData;
end;

А если сделать так, то утечка есть.

procedure TForm1.Button1Click(Sender: TObject);
var a:mytype;
begin
a:=getData;
end;


 
Джо ©   (2007-01-11 09:45) [17]

> [16] oxffff ©   (11.01.07 08:56)
> Это не верно!!!
> Динимические массивы не размещены на стеке!!!

Сама переменная массива — размещена. Его елементы, разумеется, нет.


> Вот пример.

И зачем опять извращаться со счетчиком ссылок?


 
oxffff ©   (2007-01-11 10:14) [18]


> Джо ©   (11.01.07 09:45) [17]
> > [16] oxffff ©   (11.01.07 08:56)
> > Это не верно!!!
> > Динимические массивы не размещены на стеке!!!
>
> Сама переменная массива — размещена. Его елементы, разумеется,
>  нет.


Цитата А.П. : "Массив размещен на стеке".

Где здесь речь о переменной?

>И зачем опять извращаться со счетчиком ссылок?

Этот пример исключительно показать, что можно как и в [0].
Указать, что его get функция [0] корректна.


 
oxffff ©   (2007-01-11 10:21) [19]

to Джо

Цитата А.П. "Массив размещен на стеке и прекращает свое существование
при выходе из процедуры"

Ответ неверный. Тогда было и бы AV.


 
tesseract ©   (2007-01-11 10:43) [20]


> oxffff ©   (11.01.07 08:56) [16]


А pointer(a) счётчик ссылок не увеличит?


 
oxffff ©   (2007-01-11 11:07) [21]


> А pointer(a) счётчик ссылок не увеличит?


Нет.
А с чего он вдруг должен увеличить счетчик у указателя(pointer).


 
Anatoly Podgoretsky ©   (2007-01-11 11:22) [22]


> Динимические массивы не размещены на стеке!!!

Все правильно, сбило с толку это String[$FF];



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

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

Наверх




Память: 0.52 MB
Время: 0.035 c
9-1131554360
2Wish
2005-11-09 19:39
2007.03.04
Изометрия


15-1171109407
xayam
2007-02-10 15:10
2007.03.04
Кто-нибудь сталкивался?


9-1145028173
grisme
2006-04-14 19:22
2007.03.04
Небо на OpenGL


2-1171397906
иван8511
2007-02-13 23:18
2007.03.04
Удаление старых файлов


3-1165832104
dest
2006-12-11 13:15
2007.03.04
Insufficient memory for this operation