Форум: "Начинающим";
Текущий архив: 2008.01.06;
Скачать: [xml.tar.bz2];
ВнизУказатели Найти похожие ветки
← →
unknowing (2007-12-08 21:19) [0]type
PMyRec = ^TMyRec;
TMyRec = record
B: Byte;
I: Integer;
end;
implementation
{$R *.dfm}
function GetRes : TMyRec;
begin
Result.B:= Ord("A");
Result.I:=0;
end;
function GetResP : PMyRec;
begin
GetMem(Result,Sizeof(TMyRec));
Result^.B:= Ord("B");
Result^.I:=1;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetRes;
GetResP;
end;
Здравствуйте, уважаемые мастера! Мой вопрос: в каких случаях используют подобные указатели (в моем примере PMyRec)?
← →
homm © (2007-12-08 21:30) [1]> [0] unknowing (08.12.07 21:19)
> подобные указатели
Чем подобные указатели отличаются от неподобных? А вообще, вопрос очень странный, такое чувство, что на самом деле не это хотел спросить.
← →
Джо © (2007-12-08 21:36) [2]> Мой вопрос: в каких случаях используют подобные указатели
> (в моем примере PMyRec)?
Ну, вот в вашем же примере и видно, зачем.
Для динамического управления памятью. Почему же не просто указатель, а типизированный? А потому, что удобно и практЫчно.
Какой вопрос, такой и ответ, не обессудьте :)
← →
{RASkov} © (2007-12-08 21:43) [3]Вопрос не странный.... вопрос вполне нормальный а вот ответить коротко на него трудно....
В приведенном коде я не вижу смысла в GetResP, отсюда следует, что тип PMyRec = ^TMyRec; (типизированный указатель) - не к чему...
Не так давно здесь на форуме этот вопрос(или похожий) был уже, и на него был отличный ответ подкрепленный кодом... Вот только ответившего не помню :( Помоему Ю. Зотов.... Мне тот ответ очень понравился....
Если утрированно, то указатели остались в основном для совместимости, и нет надобности в их использовании, только в специфичиских случаях, например, в своеобразных списках, но и в них уже сейчас мало нужды...
С другой стороны - нетипизированные указатели довольно широко используються, например в АПИ
← →
unknowing (2007-12-08 21:47) [4]
> Если утрированно, то указатели остались в основном для совместимости,
> и нет надобности в их использовании, только в специфичиских
> случаях, например, в своеобразных списках, но и в них уже
> сейчас мало нужды...
Ура!!! Я не понимал зачем все это.. если можно просто Trec и без явной работы с памятью!
← →
Anatoly Podgoretsky © (2007-12-08 21:52) [5]Так твой код тоже абсолютно не понять, с одной стороны функции, а с другой плюем на них.
← →
unknowing (2007-12-08 21:54) [6]
> Джо © (08.12.07 21:36) [2]
А к чему динамическое управление памятью? Какие преимущества?
← →
Anatoly Podgoretsky © (2007-12-08 21:56) [7]> unknowing (08.12.2007 21:54:06) [6]
Ближе к конкретике, а то говорить про погоду на Марсе как то неинтересно.
← →
unknowing (2007-12-08 21:56) [8]
> Anatoly Podgoretsky © (08.12.07 21:52) [5]
begin
MyB:=GetRes.B;
MyBp:=GetResP^.B;
end;
← →
Anatoly Podgoretsky © (2007-12-08 21:58) [9]> unknowing (08.12.2007 21:56:08) [8]
Непонятно, что эти переменные здесь делают, они никак не используются.
Применение того или другого вида определяется задачей.
← →
unknowing (2007-12-08 21:59) [10]
> Anatoly Podgoretsky © (08.12.07 21:58) [9]
Конкретизирую вопрос. В каких видах задач лучше/практичней/продуктивней/пр. используют указатель?
← →
antonn © (2007-12-08 22:02) [11]в списках, где укзатели указывают на большие куски памяти :)
не собирать же их все в один массив :)
← →
unknowing (2007-12-08 22:03) [12]
> antonn © (08.12.07 22:02) [11]
Если Вас не затруднит, приведите пример.
← →
{RASkov} © (2007-12-08 22:03) [13]> [6] unknowing (08.12.07 21:54)
> Какие преимущества?
Скорость.
Но опять же смотря в каких случаях в приведенном тобой нет преимущества...
> [10] unknowing (08.12.07 21:59)
Вот в данном случае без указателя никак:
TRec = record
param: Integer;
Next: PRec;
end;
PRec = ^TRec;
← →
Anatoly Podgoretsky © (2007-12-08 22:04) [14]Задачи разные бывают. Если задаче требуется динамическое выделение памяти, то так тому и быть. Но если это не требуется, а программист сует не нужное, то это плохо.
Приведеные два варианта не конечные.
Пока реальных вопросов не видать.
А использовать можно, что угодно и как угодно.
За последнии несколько лет мне не потребовалось динамически выделять память под переменные (типы), хватает или глобальных или локальных простых переменных или динамических массивов, а также классов. Нужды строить списки нет.
← →
unknowing (2007-12-08 22:09) [15]
> Anatoly Podgoretsky © (08.12.07 22:04) [14]
Если Вас не затруднит, приведите пример с необходимостю динамического выделения памяти.
← →
Anatoly Podgoretsky © (2007-12-08 22:11) [16]> unknowing (08.12.2007 22:09:15) [15]
Ты имеешь в виду наверно ручное выделение памяти, в наше время необходимости не вижу, есть альтернативные методы. Будет необходимость в N направленых списках вот тогда может появиться необходимость.
← →
unknowing (2007-12-08 22:15) [17]
> Anatoly Podgoretsky © (08.12.07 22:11) [16]
Про глобальные переменные... (оффтоп) Делаю так: считываю данные с сом-порта, типа, GetBuff, все что пришло передаю в парсер ParseBuf(GetBuff.data), если сообщение закончено, то заполняю глобальную переменную-запись и в цикле 10 Гц выдаю ее значения на экран... Так делают профи или нет ? :)
← →
Anatoly Podgoretsky © (2007-12-08 22:24) [18]> unknowing (08.12.2007 22:15:17) [17]
Ничего не понятно, как это связано с Дельфи?
← →
unknowing (2007-12-08 22:29) [19]
> Anatoly Podgoretsky © (08.12.07 22:24) [18]
Просто пытаюсь делать на Delphi. Все работает, но у программистов-профессионалов есть, вроде, понятие "хороший стиль". Поэтому интересно, так организовывается обмен, а Delphi просто инструмент...
← →
antonn © (2007-12-08 22:39) [20]
> unknowing (08.12.07 22:03) [12]
>
>
> > antonn © (08.12.07 22:02) [11]
>
> Если Вас не затруднит, приведите пример.
>
ну смотри. Например у тебя компонент, в котором хранится множество картинок (типа TImageList, но честно - не знаю как он устроен). Можно картинки хранить в одном битмапе последовательно. И когда их запросят - копировать через canvas.rect() на нужный канвас учитывая сдвиг. Итого один массив на все картинки.
А можно сделать Tlist, в который помещать указатели на динамически создаваемые Tbitmap (один битмап - одна картинка). Из плюсов - картинки могут быть в разных палитрах, разных размеров. Из минусов - потерял указатель - утекла память.
← →
Anatoly Podgoretsky © (2007-12-08 22:43) [21]> antonn (08.12.2007 22:39:20) [20]
А есть TObjectList это что бы не терять.
← →
unknowing (2007-12-08 22:44) [22]
> antonn © (08.12.07 22:39) [20]
Спасибо большое! Попробую понять!
← →
unknowing (2007-12-08 23:08) [23]Спасибо все отозвавшимся!
← →
antonn © (2007-12-08 23:11) [24]
> Anatoly Podgoretsky © (08.12.07 22:43) [21]
>
> > antonn (08.12.2007 22:39:20) [20]
>
> А есть TObjectList это что бы не терять.
ну я в общем. Считаю полезно руками собрать то, что уже есть - грабли появляются, сразу лучше понимаешь - что написать что то стоящее и работающее не просто :)
хм.. А в timagelist все картинки хранятся в одном битмапе? интересно просто :)
← →
homm © (2007-12-08 23:36) [25]> [10] unknowing (08.12.07 21:59)
> Конкретизирую вопрос. В каких видах задач лучше/практичней/продуктивней/п
> р. используют указатель?
Я же говорил, что ты не то спросил ;)
> [24] antonn © (08.12.07 23:11)
> хм.. А в timagelist все картинки хранятся в одном битмапе?
> интересно просто :)
Вроде да.
← →
Юрий Зотов © (2007-12-08 23:52) [26]> unknowing (08.12.07 23:08) [23]
Например, пусть устройство имеет такой протокол обмена:
- сначала передает 4 байта, в которых содержится объем информации, которая сейчас будет передана;
- затем передает саму информацию.
Попробуйте написать читающую программу без использования динамической памяти.
И сразу все поймете.
:о)
← →
Юрий Зотов © (2007-12-09 00:03) [27]Уточнение - и оба раза устройство ждет подтверждения приема.
← →
Германн © (2007-12-09 00:11) [28]
> Юрий Зотов © (08.12.07 23:52) [26]
Начал читать ветку решил в качестве варианта привести мою работу с внешними устройствами. Но увы опоздал.
← →
MetalFan © (2007-12-09 11:01) [29]1. в случае использования внутри программ на делфи память под тип.указатели лучше выделять/освобождать с пом New/Dispose.
в этом случае будет корректно освобождена память из под длинных строк и дин.массивов.
пример:type
PNodeData = ^TNodeData;
TNodeData = record
Name: string;
Code: string;
Pos: array of integer;
end;
...
var
lNodeData: PNodeData;
...
New( lNodeData );
...
lNodeData^.Name := SomeString;
lNodeData^.Code := SomeCode;
SetLength( lNodeData^.Pos, 10 );
lNodeData^.pos[0] :=....;
....
....
Dispose( lNodeData ); //вся память, выделенная под данные в записи будет корректно освобождена
2. Для удобства работы с данными в памяти, возвращаемыми/передаваемыми WinAPI функциями
Пример:var
lData: PInternetCacheEntryInfo;
begin
lData := nil;
lEntSize := 0;
if (FindFirstUrlCacheEntry( nil, lData^, lEntSize ) = 0) and
(GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
GetMem( lData, lEntSize );
lData^.dwStructSize := SizeOf(TInternetCacheEntryInfo);
lEnumHandle := FindFirstUrlCacheEntry( nil, lData^, lEntSize );
...
← →
homm © (2007-12-09 11:25) [30]> [29] MetalFan © (09.12.07 11:01)
> вся память, выделенная под данные в записи будет корректно
> освобождена
Я в шоке. А как рантайм узнает, что ему нужно освободить строки и массивы?
← →
MetalFan © (2007-12-09 12:39) [31]
> homm © (09.12.07 11:25) [30]
RTTI
← →
Leonid Troyanovsky © (2007-12-09 12:50) [32]
> antonn © (08.12.07 23:11) [24]
> хм.. А в timagelist все картинки хранятся в одном битмапе?
> интересно просто :)
Хз.
Хранятся они в некоторой внутренней структуре, но скормить ей
можно BITMAP полоской, шириной в n картинок.
См., например, IImageList::Add Method
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-12-09 12:56) [33]
> MetalFan © (09.12.07 12:39) [31]
> RTTI
Почему RTTI?
Скорее уж к-н compiler magic.
--
Regards, LVT.
← →
unknowing (2007-12-09 13:28) [34]
> Юрий Зотов © (08.12.07 23:52) [26]
Понял Вас! Если объем передаваемых данных может меняется (недетерминирован, блин), тогда, действительно, не обойтись без динамического выделения.... Но мой вопрос про обмен связан с логикой и принципом построяния программы обмены. К меня идет непрерывный обмен(односторонний). Ус-во посылает данные в формате ID [data] (символьно). Делаю так:
...
type TRSData = packed record
I : Integer;
W : Word;
end;
var //глобальная
RSData : TRSData;
procedure GetBuff();
begin
... //принимаю сиволы с порта (ус-во передает с частотой 5 Гц)
end;
procedure Parse();
begin
... разбираю принятые символы и заполняю структуру RSData
//условно If PacketDataStatus = complete then
begin
RSData.I := PAcketDataI;
RSData.W := PAcketDataW;
end;
end;
//отображаю на компонентах LAbel
procedure Timer(); делаю его с частотой 10 Гц//
begin
Label1.Caption:= IntToStr(I);
Label2.Caption:= IntToStr(W);
end;
Так делают профи? Или опять дилетантств?! ;)
← →
MetalFan © (2007-12-09 13:30) [35]
> Leonid Troyanovsky © (09.12.07 12:56) [33]
а почему и нет?
например:
type
PSomeRec = ^TSomeRec;
TSomeRec = record
Name: string;
Arr: array [0..1024] of byte;
end;
var
lPVar: PSomeRec;
lPtr: Pointer;
begin
New( lPVar );
SetLength( lPVar^.Name, 1024*1024);
lPtr := lPVar;
Dispose( lPtr ); //память нифига не освободилась
//Dispose( PSomeRec(lPtr); //а если сделать так,то все ок
end;
разве RTTI тут не при чем?
поправьте, если ошибаюсь
← →
Anatoly Podgoretsky © (2007-12-09 13:31) [36]> unknowing (09.12.2007 13:28:34) [34]
Пока не видно ни динамического (ручного) выделения памяти и необходимости в нем.
← →
unknowing (2007-12-09 13:34) [37]
> Anatoly Podgoretsky © (09.12.07 13:31) [36]
В оффтоп вопрос. Про построение (логику) программы обмена...
← →
Leonid Troyanovsky © (2007-12-09 15:21) [38]
> MetalFan © (09.12.07 13:30) [35]
> разве RTTI тут не при чем?
Ты выдвинул тезис, тебе и обосновывать.
Посмотри CPU, какой код генерируется при вызовах
Dispose( PSomeRec(lPtr)) vs Dispose((lPtr))
Во втором случае вызов Finalize отсутствует.
--
Regards, LVT.
← →
antonn (work) (2007-12-09 15:28) [39]
> Хранятся они в некоторой внутренней структуре, но скормить
> ей
> можно BITMAP полоской, шириной в n картинок.
да я в кусре, сохраняются они тоже в одном битмапе (правда не полоской :)). Но все не доберусь к компу с дельфей посмотреть.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.06;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.006 c