Текущий архив: 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.047 c