Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.09.11;
Скачать: [xml.tar.bz2];

Вниз

Typed pointer   Найти похожие ветки 

 
Empleado   (2003-08-28 20:00) [0]

Есть 2 типа:

PA = ^TA;
TA = record
x, y: integer
end;

TB = TBookmark;

Есть процедура Proc(P: pointer). P может принадлежать к одному из этих типов.
В этой процедуре надо сделать рилиз памяти, занимаемой Р.

Можно ли сделать такое? Если "да", как это сделать правильно?

Так понимаю, что если РА, то используем Dispose(P)
если ТВ - то FreeMem(P). Но кажется мне, что ни так все просто :)

Gracias


 
Skier   (2003-08-28 20:27) [1]

если ТВ - то TDataSet.FreeBookmark(...)


 
Романов Р.В.   (2003-08-28 22:07) [2]

TPointerType = set of (ptRecord, ptBookmark);
...
Proc(P: pointer; Tp: TPointerType);


 
Fantasist   (2003-08-29 01:05) [3]

Используй class вместо record. Настоятельно рекомендую.


 
о   (2003-08-29 01:26) [4]

Так понимаю, что если РА, то используем Dispose(P)
>если ТВ - то FreeMem(P).


это смотря как ты память выделял. ничего не сказал об этом. если из кучи (Дельфийской) - то Dispose. если из виртуальной памяти -VirtualFree и тд... а если из стека то ничего и освобождать не надо...


 
Empleado   (2003-08-29 12:58) [5]

>Романов Р.В. © (28.08.03 22:07) [2]
Совершенно верно, именно этот вариант и работает в наст. время.
>Fantasist © (29.08.03 01:05) [3]
Согласен, можно использовать class, создать 2 свойства и рушить все в Destroy.

Немного конкретики:

type
PA = ^TA;
TA = record
x, y: integer
end;

var P: Pointer;

implementation

procedure ReleaseMyPtr(P: Pointer);
begin
..... -?
end;

procedure DoSomething;
begin
if MyCondition then begin
New(P);
P^ := GetTA;
end
else P := Dataset.GetBookmark;
.....
ReleaseMyPrt(P)
end;


Вопрос: Как должна выглядеть ReleaseMyPtr, чтобы корректно освобождать память?


 
Skier   (2003-08-29 13:03) [6]

procedure ReleaseMyPtr(P: Pointer);
begin
FreeMem(P);
end;


 
Empleado   (2003-08-29 13:33) [7]

Извиняюсь, ошибка. Правильно будет так:

type
PA = ^TA;
TA = record
x, y: integer
end;

var P: Pointer;

implementation

procedure ReleaseMyPtr(P: Pointer);
begin
..... -?
end;

procedure DoSomething;
var Ptr: PA;
begin
if MyCondition then begin
New(Ptr);
Ptr^ := GetTA;
.....
P := Ptr
end
else P := Dataset.GetBookmark;
.....
ReleaseMyPrt(P)
end;


 
Empleado   (2003-08-29 15:34) [8]

>Skier © (29.08.03 13:03) [6]
И совершенно нет разницы - как эта переменная создавалась: New или GetMem?
И не надо знать тип данных и размеры занимаемой памяти?


 
Skier   (2003-08-29 15:35) [9]

>Empleado © (29.08.03 15:34)


> И совершенно нет разницы - как эта переменная создавалась:
> New или GetMem?


Для твоего случая - нет.


 
Skier   (2003-08-29 15:35) [10]

>Empleado © (29.08.03 15:34)


> И совершенно нет разницы - как эта переменная создавалась:
> New или GetMem?


Для твоего случая - нет.


 
Erik   (2003-08-29 16:04) [11]

Вы чего мозги пудрите если невыразится грубее или пятница :)
Да немайся дурю просто сделай
procedure DoSomething;
var Ptr: PA;
MyVar: TA;
begin
if MyCondition then begin
Ptr := @MyVar
Ptr^ := GetTA;
.....
P := Ptr
end
else P := Dataset.GetBookmark;
.....
ReleaseMyPrt(P) - здесь всегда Dataset.FreeBookmark(P)
end;


 
Fantasist   (2003-08-29 18:43) [12]


> Erik (29.08.03 16:04) [11]


Мда... Даже не знаю, как прокомментировать. Но большей чуши редко приходиться видеть. Мало того, что делается попытка вызвать FreeMem для стекового объекта, так еще и делается это в такой завуалированной форме.

Честно говоря, на мой взгляд лучше четко разделить твой pointer и TBookmark и обрабатывать их по разному. Несмотря на то, что под TBookmark"ом делается те же GetMem/FreeMem. Если уж так хочеться объеденить их напиши класс обертку. Что нибудь типа:

TPtrType=(ptBookmark,ptTA);

Ptr=class
private
fType:TPtrType;
p:pointer;
public
constructor Create;
{
fType:=ptTA;
New(PTA(p));
}

constructor Create(DT:TDataSet);
{
fType:=ptBookmark;
p:=DT.GetBookmark;
}

property A:TA read { if fType<>ptTA then raise Exc.Create; Result:=p; }

property Bookmark:TBookmark read { if fType<>ptBookmark then raise Exc.Create; Result:=p; }

end;


Ну и Destroy соответсвующий. Лучше, на самом деле, то же самое, только с наследованием и виртуальным функциями и деструктором. А так начнешь их мешать, и когда-нибудь будешь долго разбираться в каком-нибудь куске кода, что это за указатель у тебя такой.


 
Empleado   (2003-08-29 20:08) [13]

>Fantasist © (29.08.03 18:43) [12]
Действительно, это не плохой вариант.

Сразу скажу, что спешной производственной необходимости в решении этого вопроса нет. Это вопрос не из экстремального программирования ("если не сдам, то...").
Процедура работала (и работает) по принципу, указанному в Романов Р.В. © (28.08.03 22:07) [2], т.е. передаю заранее информацую о типе данных, затем вызываю соответствующий метод.
Вопрос этот больше для меня самого. Хотелось бы разобраться и понять; и спасибо тем, кто откликнулся.

Перейду к теме.
Я не до конца понял ответ:
Skier © (29.08.03 13:03) [6] + Skier © (29.08.03 15:35) [9]

Если я правильно понимаю, разница м-ду New и GetMem заключается в том, что New, грубо говоря, сам заботится о выделении памяти для данных, на которые ссылается указатель, используя тип указателя. Чтобы освободить память - вызываем Dispose, либо FreeMem, указывая соответствующий size. В GetMem все вручную.

Для моего примера ( Empleado © (29.08.03 13:33) [7]) было предложено использовать FreeMem, независимо от типа данных указателя.
Если указатель является TBookmark (= pointer), то понятно - просто делается FreeMem на 4 байта.
Но как поймет процессор, что надо освободить SizeOf(TA), при вызове ReleaseMyPrt(P), где для P было := Ptr (типа PA) ?

Спасибо за разъяснения/пояснения.
Gracias


 
Романов Р.В.   (2003-08-29 22:58) [14]

Можно пойти по типу переменной вариант, т.е. тип данных хранить в самой структуре



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.09.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.008 c
3-33427
Jean
2003-08-21 22:20
2003.09.11
Access + Excel


3-33458
zzzrrv
2003-08-21 09:51
2003.09.11
Индексирование Dbf


1-33672
Aleksandr
2003-08-29 15:22
2003.09.11
Как узнать, какой объект вызвал TAction?


3-33488
BigError
2003-08-18 15:34
2003.09.11
QuantumGrid, MySQL - как заставить Cells сохранять данные сразу?


11-33532
microlab
2003-01-04 08:23
2003.09.11
TKOLTreeView c переклучателями





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский