![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Указатели [D7, WinXP]
GlTech © (2009-08-21 09:25:00)Уважаемые программисты!
Помогите разобраться со следущим вопросом:
каким образом в нижеприведенном коде
переменная 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;
Буду очень признателен за ответы.
Спасибо.
Amoeba (2009-08-21 13:51:00) [1]
> GlTech (21.08.09 13:48) [10]
>
> Приму на вооружение. Тем более, что есть в наличии.
> Спасибо.
>
Классиков надо не только почитАть, но и почИтывать.
GlTech (2009-08-21 13:48:00) [2]Приму на вооружение. Тем более, что есть в наличии.
Спасибо.
Kolan (2009-08-21 13:43:00) [3]А книжку я вам советовал не для ознакомления с работой с памятью, а для знакомства с работой с объектами. Мне показалось, что тут у вас есть пробелы, а эта книжка все подробно рассказывает.
:)
GlTech (2009-08-21 13:40:00) [4]
> Вы берете и кладете в n1 адрес из n теперь обе переменные
> указываеют на то, что вернула TreeView1.Items.Add(nil,
> 'Test');. Теперь вы в n2 кладете адрес из n1 и теперь все
> трое указывают на созданный нод.
ОК, все ясно.
Спасибо, что не пожалели время на ответы.
Kolan (2009-08-21 13:04:00) [5]
> Тогда в чем отличие записи 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:00) [6]в моем понимании, и происходит ситуация создания указателя на указатель
происходит присвоение значения одного указателя значению другого.
после чего получаются два казателя на одно и тоже
GlTech (2009-08-21 12:53:00) [7]Хорошо, спасибо!
Про автоматическое распределение динамической памяти при объявлении переменной прошу прощения, не так выразился. Понятно, что эта переменная-указатель может либо указывать на адрес с уже распределенной памятью для соответствующего типа либо распределена непосредственно с помощью New и освобождена Dispose. Тогда в чем отличие записи n: TTreeNode и n: ^TTreeNode ? И в одном и в другом случае это указатели ?;
Что по поводу книги, то но не уверен, что в книге Стива Тейксейры и Ксавье Пачеко работа с указателями и памятью расписана более подробно, чем в Энциклопеции Delphi Чарльза Калверта несмотря на 2 тома против одного.
Но все равно посмотрю.
Еще раз спасибо.
Kolan (2009-08-21 12:37:00) [8]Вообще прочтите книгу Delphi 5 Руководство разработчика, там все рассказано весьма понятно.
Kolan (2009-08-21 12:36:00) [9]Объявление переменной объекта не означает выделения памяти. Для выделения памяти его надо создать.
Со строками сложнее. Это тип с управляемым временем жизни. Это значит, что компилятор сам выделяет и освобождает память. Это называется compiler magic.
GlTech (2009-08-21 12:19:00) [10]Благодарю за ответ на мой вопрос.
Позволю себе один комментарий:
Я понимаю, что объявление любой переменной, указывающей на объект или на другую переменную - это, по сути, объявление типизированного указателя с распределенной для него памятью (аналогNew(pn), гдеpn: ^TTreeNodeили
pn: ^integer, не важно какой тип), тогда получается, что переменная n2 (первый пример кода) указывает на ячейку памяти с адресом @n1, который, в свою очередь содержит указатель на ячейку памяти с адресом @n, где фактически распределена структура TTreeNode. Или же я что то не правильно понимаю ? Отсюда напрашивается вопрос: каким образом строка кода:
n2.Text := 'Test1'
вызывает изменение данных по адресу @n ?
Как раз, в случае записи:n1 := n; n2 := n1, в моем понимании, и происходит ситуация создания указателя на указатель (в адресе @n2 должен, по идее, храниться адрес @n1, а в адресе @n1 - храниться адрес @n), а фактически, получается, что все 3 указателя указывают на одну и ту же область памяти с адресом @n ?
MBo (2009-08-21 09:34:00) [11]Память одна и та же.
TTreeNode, как и любой объект - указатель.
Несколько указателей указывают на один объект, вот и все.
> pn: ^TTreeNode;
указатели на указатели без особой нужды не используются.