Текущий архив: 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.48 MB
Время: 0.008 c