Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.48 MB
Время: 0.038 c
1-1093007371
kukuikar
2004-08-20 17:09
2004.09.05
хранение пароля на запуск программы....


14-1092384888
User_OKA
2004-08-13 12:14
2004.09.05
Полифония wav


3-1091777163
pepper
2004-08-06 11:26
2004.09.05
Проверка корректности заполнения полей базы


8-1087834552
XGarik
2004-06-21 20:15
2004.09.05
Надпись на картинке JPG


4-1090300887
[BAD]Angel
2004-07-20 09:21
2004.09.05
Как получить PID процессов?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский