Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
ВнизПравильное использование Dispose()... Найти похожие ветки
← →
3APA3A © (2004-08-19 21:33) [0]type
TMyType = record
....
end;
var A : array of pointer;
В процедуре
var MyType : ^TMyType;
begin
New(MyType);
A[1] := MyType;
end;
Так вот - нужно ли при уничтожении делать так
var MyType : ^TMyType;
begin
MyType := A[1];
Dispose(MyType);
end;
или достаточно вот так
begin
Dispose(A[1]);
end;
← →
jack128 © (2004-08-19 21:50) [1]
> или достаточно вот так
> begin
> Dispose(A[1]);
> end;
смотря какого типа A[1]. Если ^MyType, то достаточно так. Если поинтер, то помниться компилятор должен ругаться..
← →
3APA3A © (2004-08-19 22:02) [2]Нет... Процедура Dispose() описана как
procedure Dispose(P : Pointer);
=> можно писать и Dispose(A[1]), где A[1] - Pointer... (проверил - компилятор не ругается)
Мне просто интересно, будет ли все правильно работать...
P.S. Хотя я сейчас поразмыслил - Dispose() определяет кусок выделеной памяти только по адресу => можно писать "что угодно"...
P.P.S. Просто интересен механизм выделения памяти через New(), Dispose()... Получается, что система создает некий "массив", типа (адрес, размер) и по адресу уже ищет в этом "массиве" размер освобождаемой памяти? Так?
← →
jack128 © (2004-08-19 22:28) [3]
> ... (проверил - компилятор не ругается
имхо - зря.
> Мне просто интересно, будет ли все правильно работать...
>
зависит от описания MyType. Если в этой записи будут длинные строки, дин массивы, интерфейсы и тд, то ИМХО - будет мем лик(а проверять - лень ;)). Для типизированных указателей Dispose() - делает файнализацию всех подобных объектов, а для нетипизированных - нет.
← →
Гаврила © (2004-08-19 23:04) [4]
> jack128 © (19.08.04 22:28) [3]
ПОскольку тип MyType определен ,мем лика быть не должно. В том числе и при наличии там длинных строк ,и т.д, так как финалайз будет вызван для каждого элемента
> или достаточно вот так
> begin
> Dispose(A[1]);
> end;
ИМХО. достаточно. Хотя я обычно подстраховываюсь - передаю типизированный указатель.
А вообще, посмотри в ассемблере, что происходит в этом случае :-)
← →
jack128 © (2004-08-19 23:19) [5]
> ПОскольку тип MyType определен ,мем лика быть не должно.
> В том числе и при наличии там длинных строк ,и т.д, так
> как финалайз будет вызван для каждого элемента
Какая разниза, что MyType определен, если A[1] - Pointer? Как компилятор узнает какой код файнализации генерить для указателя неизвестно на что. Посмотри в окне CPU - сам увидешь для Pointer"a Dispose эквивалентен FreeMem
← →
3APA3A © (2004-08-19 23:58) [6]1) В описании MyType - только простые типы данных (Cardinal, Int64 и т.д.)
2) Что такое мем лик?
3) Посмотрел на asm"е. Там такая картина
При Dispose(A[0])
mov eax, [тот самый Pointer]
xor edx, edx
call @FreeMem
При Dispose(MyType)
mov eax, [опять тот самый Pointer]
mov edx, $0c ; Заметьте, что размер структуры TMyType, выровненный на границу 4 байта - 12 байт...
call @FreeMem
То есть - когда передаем "голый" Pointer - в процедуру FreeMem передается размер выделенной памяти = 0, когда передаем типиз. указатель - передается реальный размер...
Таковы мои выводы...
Верны ли они и что все это значит?
← →
jack128 © (2004-08-20 00:28) [7]
> 1) В описании MyType - только простые типы данных (Cardinal,
> Int64 и т.д.)
тогда без разницы
> 2) Что такое мем лик?
memory leak - утечка памяти. Когда походу выполнения программы теряется указатель на выделеную память её нельзя освободить до конца пыполнения программы.
> 3) Посмотрел на asm"е. Там такая картина
Это уже интересней. У меня (D5) картина несколько иная
procedure TForm1.Button1Click(Sender: TObject);
var
ps: PString;
p: Pointer;
begin
new(ps);
ps^ := StringOfChar(#0, 1024*1024);
p := ps;
Dispose(p);
// Dispose(ps);
end;
Для случая Dispose(p)
mov eax, ebx // p := ps
xor edx, edx // вот зачем это нужно я так и не понял..
call @FreeMem
Для случая Dispose(ps)
mov edx, [$0040168] // хз, что это такое, но скорее всего какая то информация, по которой можно коректный Finalize сделать
mov eax, ebx - наш указатель
call $Dispose - а из этой процедуры вызывается процедура Finalize
← →
jack128 © (2004-08-20 00:32) [8]
> FreeMem
>
>
> То есть - когда передаем "голый" Pointer - в процедуру
> FreeMem передается размер выделенной памяти = 0, когда передаем
> типиз. указатель - передается реальный размер...
> Таковы мои выводы...
>
да верны. Я совсем забыл уже что у тебя простые типы. Все правельно.
← →
jack128 © (2004-08-20 00:33) [9]Но на будущее, коли ты выделил память под типизированный указатель, то и освобождай его как типизированный Dispose(PMyType(A[1]));
← →
3APA3A © (2004-08-20 03:46) [10]1) Сейчас попробовал Ваш код в D7 - asm код абсолютно тот же...
2) Посмотрел, что такое $0040168 - это
а) [$0040168] = $0040168 + 4; (хотя может быть так не всегда, но в моих тестах было постоянно)
б) по тому адресу, который хранится в [$0040168] находятся следующие байты
0A 06 53 74 72 69 6E 67... два первых байта не менялись с изменением размера и содержимого строки (хотя по моему - они и не должны менятся, это что-то другое...), а 6 последних байт - это слово "String" в ASCII кодировке... мда... (да, а если посмотреть еще дальше - там адрес, по которому "лежит" строка "TObject"...=))... То есть - чем дальше в лес - тем толще партизаны...=) Все непонятней и непонятней...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.033 c