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

Вниз

Утечка памяти при передаче нити дин. массива как параметра.   Найти похожие ветки 

 
Riply ©   (2007-03-01 12:10) [0]

Утечка происходит только, если мы выходим из нити при помощи EndThread
Пока эксперементировала с MsgWaitForMultipleObjects,
нетолкнулась на следущее:
type
PStopEventsArr = ^TStopEventsArr;
TStopEventsArr = array of THandle;

function ListenThread(EventsArr: TStopEventsArr): DWord;
begin
Result := 0;
if EventsArr[0] = 0 then EndThread(0) else
 if EventsArr[0] = 1 then Exit else Windows.Beep(100, 100);
end;

и вызов:
var
StopArr: TStopEventsArr;
begin
SetLength(StopArr, 2);
StopArr[0] := 0;
hThread := BeginThread(nil, 0, @ListenThread, StopArr, 0, ThreadID);

В этом случае, при закрытии программы ReportMemoryLeaksOnShutDown
выдает следущее:
"Unexpected Memory Leak
An unexpected memory leak has occurred. The unexpected small block leaks are:  13 - 20 bytes: Unknown x 1"
Если мы StopArr[0] присвоим единицу, то утечки не будет.
Так же не будет утечки при любом StopArr[0], если передавать не массив, а указатель на него:
function ListenThread(pEventsArr: PStopEventsArr): DWord;
begin
Result := 0;
if pEventsArr^[0] = 0 then EndThread(0) else
 if pEventsArr^[0] = 1 then Exit else Windows.Beep(100, 100);
end;

и вызов:
hThread := BeginThread(nil, 0, @ListenThread, @StopArr, 0, ThreadID);
Объясните, пожалуйста, почему при передаче дин. массива (ведь он тоже указатель),
если используется EndThread, то утечка есть, если Exit - то нет.
И почему при передаче указателя на массив, утечки нет в любом случае ?


 
Сергей М. ©   (2007-03-01 12:31) [1]

Динамический массив - это тип данных с контролируемым (управляемым компилятором) временем жизни.

Вызов оператора Exit приводит к генерации компилятором неявного кода, отвечающего за финализацию (если она требуется) локальных переменных и фактических параметров дин.типа (длинные строки, дин.массивы и т.п.), таким образом компилятор облегчает работу программера, взяв на себя функции по освобождению явно неосвобождаемой программером памяти, занятой данными дин.типа.

Вызов EndThread приводит к немедленному завершению поточной функции, при этом компилятор не несет никакой ответственности за вышеупомянутую финализацию, т.е. неявной финализации как таковой не происходит.

В случае с передачей параметра типа TStopEventsArr компилятор фактически передает копию дин.массива, который, разумеется, подлежит явной или неявной финализации при завершении поточной ф-ции.


 
Riply ©   (2007-03-01 13:25) [2]

>[1] Сергей М. © (01.03.07 12:31)
Спасибо.
Я правильно поняла:
Получается, что при передаче параметра типа TStopEventsArr,
создается копия дин.массива, которая и передается, а не указатель на наш массив ?
Иными словами в функцию:
function ListenThread(pEventsArr: PStopEventsArr): DWord;
передается только указатель,
а в
function ListenThread(EventsArr: TStopEventsArr): DWord;
аж целый массив ?


 
Сергей М. ©   (2007-03-01 13:31) [3]


> Riply ©   (01.03.07 13:25) [2]


Судя по факту утечки в случае с TStopEventsArr именно так дело и обстоит, иного объяснения этому "феномену" я не вижу)..


> копия дин.массива, которая и передается, а не указатель
> на наш массив ?


С одним лишь уточнением - передается таки указатель, но он указывает не на оригинал, а на копию, которая и подлежит явной или неявной финализации.


 
Сергей М. ©   (2007-03-01 13:37) [4]


> Riply


А что тебя так заклинило на дин.массиве ?

Передавай, к примеру, TList - уж с ним точно никаких утечек не будет, если не забудешь уничтожить его в вызывающем коде


 
Riply ©   (2007-03-01 13:48) [5]

>[4] Сергей М. ©   (01.03.07 13:37)
>А что тебя так заклинило на дин.массиве ?
Не то чтобы "заклинило", просто, если чего-то не понимаю, то предпочитаю
попробовать разобраться "до конца", а не использовать другой путь.
Если оставлять за спиной "непонятки", то уж очень неуютно себя чуствуешь :)
А поняв в чем дело, можно и др. путем пойти :)


 
Sapersky   (2007-03-01 13:57) [6]

Передавай, к примеру, TList

Проще const добавить к EventsArr: TStopEventsArr.


 
begin...end ©   (2007-03-01 13:58) [7]

> Сергей М. ©   (01.03.07 13:31) [3]

> передается таки указатель, но он указывает не на оригинал,
> а на копию

Ничего не путаете?


 
Сергей М. ©   (2007-03-01 14:01) [8]


> begin...end ©   (01.03.07 13:58) [7]


Я могу, конечно, проверить, но иначе как НЕфинализацией дин.массива эту ситуацию объяснить нечем.


 
Sapersky   (2007-03-01 14:31) [9]

Счётчик ссылок увеличивается. С той же НЕфинализацией в результате.


 
Сергей М. ©   (2007-03-01 14:45) [10]


> Sapersky   (01.03.07 14:31) [9]


Пусть так. Не спорю.
Но суть одна и та же - EndThread в таких случаях не допустим.


 
Riply ©   (2007-03-01 14:51) [11]

И какое резюме ?
1. передается таки указатель
2. он указывает на оригинал
3. утечка происходит из-за увеличения счетчика ссылок
?


 
Сергей М. ©   (2007-03-01 15:02) [12]


> ?


4. Из-за EndThread() не происходит разумеющийся по всем статьям декремент сч-ка ссылок на массив, переданный параметром, что собссно и приводит к "ругани" той самой твоей "приблуды", ревностно следящей за мемликами)

Мое частное резюме - если не понимаешь механизмов компилятора в части дин.массивов, пользуй списки. Тот же упомянутый TList и все что на нем сидит



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

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

Наверх




Память: 0.5 MB
Время: 0.03 c
15-1172918421
wsw
2007-03-03 13:40
2007.03.25
Как вычилсить корень из числа типа int64? sqrt() - не помогает!


2-1173086816
sipsik
2007-03-05 12:26
2007.03.25
почему на второй форме параметический запрос не работает


15-1173040286
ArtemESC
2007-03-04 23:31
2007.03.25
PHP


8-1152533021
EV
2006-07-10 16:03
2007.03.25
32-битные изображения в Delphi


3-1167309164
evgen1
2006-12-28 15:32
2007.03.25
frReport1.Pages.Count=0?