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

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.024 c
1-33598
AlexPul
2003-09-01 13:30
2003.09.11
Консольные приложения


1-33535
DDS
2003-09-01 17:39
2003.09.11
Как сохранить WORDовский файл с картинкой внутри?


3-33527
LIK22
2003-08-19 12:49
2003.09.11
Помогите с SubString.


14-33767
jack128
2003-08-21 19:00
2003.09.11
StringVirtualTree & Win9x


7-33819
MW Programs
2003-06-24 17:32
2003.09.11
Windows XP