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

Вниз

Правильное использование 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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.045 c
1-1092907415
Maxim____
2004-08-19 13:23
2004.09.05
массив объектов


3-1091796517
}|{yk
2004-08-06 16:48
2004.09.05
По эффективности


1-1093040799
RusPutin
2004-08-21 02:26
2004.09.05
Чтение строк из текстового файла.


3-1092210206
Lika
2004-08-11 11:43
2004.09.05
Как составить оптимальный запрос?


14-1092423668
Piter
2004-08-13 23:01
2004.09.05
Как создать меню на HTML?