Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.035 c
2-1172731737
Abcdef123
2007-03-01 09:48
2007.03.25
SQL запрос


2-1173088934
Клара
2007-03-05 13:02
2007.03.25
Выпадающий список


15-1172483591
SerJaNT
2007-02-26 12:53
2007.03.25
Помогите найти книгу


15-1172479233
vajo
2007-02-26 11:40
2007.03.25
Проводник тормозит в сети


11-1151921952
Maloric
2006-07-03 14:19
2007.03.25
Как правильно вызвать chm хелп




   Наверх