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

Вниз

Указатели   Найти похожие ветки 

 
GlTech   (2009-08-21 09:25) [0]

Уважаемые программисты!

Помогите разобраться со следущим вопросом:
каким образом в нижеприведенном коде
переменная n2 указывает на ту же структуру данных, что и
переменная n. Как в этом случае распределяется память ?


procedure TForm1.Button1Click(Sender: TObject);
var
 n, n1, n2: TTReeNode;
begin
 n := TreeView1.Items.Add(nil, "Test");
 n1 := n;
 n2 := n1;
 n2.Text := "Test1";
end;


В чем отличие вышеприведенного кода от следующего:

procedure TForm1.Button1Click(Sender: TObject);
var
 n: TTReeNode;
 pn: ^TTreeNode;
begin
 n := TreeView1.Items.Add(nil, "Test");
 pn := @n;
 pn^.Text := "Test1";
end;


Буду очень признателен за ответы.
Спасибо.


 
MBo ©   (2009-08-21 09:34) [1]

Память одна и та же.
TTreeNode, как и любой объект - указатель.
Несколько указателей указывают на один объект, вот и все.

> pn: ^TTreeNode;
указатели на указатели без особой нужды не используются.


 
GlTech   (2009-08-21 12:19) [2]

Благодарю за ответ на мой вопрос.
Позволю себе один комментарий:

Я понимаю, что объявление любой переменной, указывающей на объект или на другую переменную - это, по сути, объявление типизированного указателя с распределенной для него памятью (аналог New(pn), где pn: ^TTreeNode или
pn: ^integer, не важно какой тип), тогда получается, что переменная n2 (первый пример кода) указывает на ячейку памяти с адресом @n1, который, в свою очередь содержит указатель на ячейку памяти с адресом @n, где фактически распределена структура TTreeNode. Или же я что то не правильно понимаю ? Отсюда напрашивается вопрос: каким образом строка кода:
n2.Text := "Test1"
вызывает изменение данных по адресу @n ?
Как раз, в случае записи: n1 := n; n2 := n1, в моем понимании, и происходит ситуация создания указателя на указатель (в адресе @n2 должен, по идее, храниться адрес @n1, а в адресе @n1 - храниться адрес @n), а фактически, получается, что все 3 указателя указывают на одну и ту же область памяти с адресом @n ?


 
Kolan ©   (2009-08-21 12:36) [3]

Объявление переменной объекта не означает выделения памяти. Для выделения памяти его надо создать.

Со строками сложнее. Это тип с управляемым временем жизни. Это значит, что компилятор сам выделяет и освобождает память. Это называется compiler magic.


 
Kolan ©   (2009-08-21 12:37) [4]

Вообще прочтите книгу Delphi 5 Руководство разработчика, там все рассказано весьма понятно.


 
GlTech   (2009-08-21 12:53) [5]

Хорошо, спасибо!

Про автоматическое распределение динамической памяти при объявлении переменной прошу прощения, не так выразился. Понятно, что эта переменная-указатель может либо указывать на адрес с уже распределенной памятью для соответствующего типа либо распределена непосредственно с помощью New и освобождена Dispose. Тогда в чем отличие записи n: TTreeNode и n: ^TTreeNode ? И в одном и в другом случае это указатели ?;
Что по поводу книги, то но не уверен, что в книге Стива Тейксейры и Ксавье Пачеко работа с указателями и памятью расписана более подробно, чем в Энциклопеции Delphi Чарльза Калверта несмотря на 2 тома против одного.
Но все равно посмотрю.
Еще раз спасибо.


 
Kolan ©   (2009-08-21 13:04) [6]


> Тогда в чем отличие записи n: TTreeNode и n: ^TTreeNode
> ?

В том что во втором случае вы объявили указатель на указатель.

Попросту говоря: при повседневной работе с объектами вам ^ и @ не нужны. Компилятор правильно все интерпретирует сам.


> Как раз, в случае записи: n1 := n; n2 := n1, в моем понимании,
>  и происходит ситуация создания указателя на указатель (в
> адресе @n2 должен, по идее, храниться адрес @n1, а в адресе
> @n1 - храниться адрес @n), а фактически, получается, что
> все 3 указателя указывают на одну и ту же область памяти
> с адресом @n ?


Вы берете и кладете в n1 адрес из n теперь обе переменные указываеют на то, что вернула  TreeView1.Items.Add(nil, "Test");. Теперь вы в n2 кладете адрес из n1 и теперь все трое указывают на созданный нод.


 
Медвежонок Пятачок ©   (2009-08-21 13:04) [7]

в моем понимании, и происходит ситуация создания указателя на указатель

происходит присвоение значения одного указателя значению другого.
после чего получаются два казателя на одно и тоже


 
GlTech   (2009-08-21 13:40) [8]


> Вы берете и кладете в n1 адрес из n теперь обе переменные
> указываеют на то, что вернула  TreeView1.Items.Add(nil,
> "Test");. Теперь вы в n2 кладете адрес из n1 и теперь все
> трое указывают на созданный нод.


ОК, все ясно.
Спасибо, что не пожалели время на ответы.


 
Kolan ©   (2009-08-21 13:43) [9]

А книжку я вам советовал не для ознакомления с работой с памятью, а для знакомства с работой с объектами. Мне показалось, что тут у вас есть пробелы, а эта книжка все подробно рассказывает.

:)


 
GlTech   (2009-08-21 13:48) [10]

Приму на вооружение. Тем более, что есть в наличии.
Спасибо.


 
Amoeba ©   (2009-08-21 13:51) [11]


> GlTech   (21.08.09 13:48) [10]
>
> Приму на вооружение. Тем более, что есть в наличии.
> Спасибо.
>

Классиков надо не только почитАть, но и почИтывать.



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

Текущий архив: 2009.10.18;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.013 c
15-1250675891
Yurikon
2009-08-19 13:58
2009.10.18
Контроль за использованием памяти


15-1250687810
Алчный
2009-08-19 17:16
2009.10.18
TdxSkinController


6-1205348739
Igor23
2008-03-12 22:05
2009.10.18
idhttp


15-1250659551
TUser
2009-08-19 09:25
2009.10.18
Кредит никому не надо?


10-1160635928
MaxBooster
2006-10-12 10:52
2009.10.18
Создание и вызов Delphi COM обектов из WSH