Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

^ и @ [D6, Win95/98]


Falcon(TFSoft) ©   (2004-10-19 21:55:00) 

Привет всем, помогите разобратся с операторами: ^ и @
Что они означают...
Или чем отличаються (ведт ^ - указатель возвращает а @- адресс, если я не ошибаюсь).
Спасибо...


Piter   (2004-10-20 23:02:00) [1]

begin...end ©   (20.10.04 20:07) [16]
Не могу сказать ничего определённого. Возможно, в каких-то случаях память освобождается автоматически. Но лучше освобождать её явно, вот так:

Massiv := NIL


ну ты даешь. Динамический массивы являются типом с автоматической уборкой мусора, так что не надо ничего такого делать.


begin...end   (2004-10-20 22:18:00) [2]


> [18] Falcon(TFsoft) ©   (20.10.04 22:11)


> то как его можно потом найти, по родителю что-ли?

Ну насколько я понимаю, обычно так (with TSomeClassObj.Create do) создают объект, с которым тут же и работают... Если это потомок TControl, то в Create нужно указывать Owner'а, и в принципе найти потом можно... Ну а в общем случае придётся, ИМХО, использовать дополнительную переменную:

var
 SomeClassObj: TSomeClassObj;

begin
 ...
 SomeClassObj := TSomeClassObj.Create;
 try
   // тут с ним работаем
 finally
   SomeClassObj.Free
 end;
 ...
end.


Falcon(TFsoft)   (2004-10-20 22:11:00) [3]

Нет просто я ужасный тормоз...
Я забыл убрать свои эксперементы-функции из раздела OnClose, что и явилось следствием второй ошибки. Так что огромное спасибо!

И я позволю себе ещё вопрос...
если создавать экземпляр класа методом

with TSomeClassObj.Create do
begin
 настраиваем его свойства ...
end;
то как его можно потом найти, по родителю что-ли?


begin...end   (2004-10-20 20:09:00) [4]


> [15] Falcon(TFSoft) ©   (20.10.04 20:06)

Т.е. ты хочешь сказать, что после исправлений ошибка осталась?


begin...end   (2004-10-20 20:07:00) [5]


> [12] Falcon(TFSoft) ©   (20.10.04 19:44)


> Ведь массив не объект и память из поднего высвобождается
> вроде автоматически?

Не могу сказать ничего определённого. Возможно, в каких-то случаях память освобождается автоматически. Но лучше освобождать её явно, вот так:

Massiv := NIL


Falcon(TFSoft)   (2004-10-20 20:06:00) [6]

Но ошибка всё же есть...
:(((
Она возникает именно при завершении программы, а не  при записи данных?


Falcon(TFSoft)   (2004-10-20 20:05:00) [7]

Точно... блин вот я лось .... :)


begin...end   (2004-10-20 20:00:00) [8]


> [12] Falcon(TFSoft) ©   (20.10.04 19:44)

Типичная ошибка.

> выделям память...
> SetLength (Massiv, t.count);    

Вот здесь ты выделил память под t.Count элементов.

> while i<=t.count do    

При i = t.Count цикл ещё будет выполняться.

> Massiv[i] := t.data[i];        

А вот здесь ты пытаешься записать данные в НЕСУЩЕСТВУЮЩИЙ элемент массива с индексом i. Несуществующий - потому, что для динамических массивов индексы элементов начинаются с нуля. И в данном случае индексы массива могут принимать значения 0 .. (t.Count - 1).


Falcon(TFSoft)   (2004-10-20 19:44:00) [9]

Вопрос может и косается косвенно, но меня интересует....

Помогите решить вопрос, с памятью. Возникла ситуация, при которой со спрайтом необходимо хранить динамический массив, настройки спрайта, динамический т.к. я посчитал не выгодным храниьт разное кол. данных при фиксированной длинне, но не в этом суть. Так вот по его создании я вызываю функцию, которая инициализирует их, а именно:

Procedure TImageSpriteEX_2.Init (Name: String; var ImgList: TDXImageList);
var
 i     : byte;
 t     : TAS_EX;
begin
   i := 0;
   t := MainFile.FindTAS_EX(name);
   
   выделям память...
   SetLength (Massiv, t.count);
   while i


Falcon(TFSoft)   (2004-10-20 19:42:00) [10]

Спасибо!


Юрий Зотов   (2004-10-19 23:18:00) [11]

> Falcon(TFSoft) ©   (19.10.04 22:30) [5]

> если сделать глобальный указатель, который будет уаказывать на
> адресс локальной переменной в функции, то после завершения
> времени жизни это переменной на что будет указывать этот
> указатель?

Ведь значение указателя никто не менял? Не менял. Значит, что в нем было, то и останется. Например, если в нем сидел адрес $00CA3DF1, то он в нем и будет. Программа же ничего не делает сама по себе, а делает только то, что в ней написал программист (ну, иногда еще то, что неявно добавил компилятор, но это не тот случай). Так что значение указателя не изменится.

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

А давайте подумаем - что же это значит? Как так - перестала существовать? А куда же она исчезла? Ведь не могла исчезнуть ячейка памяти, которая была отведена под эту переменную? Не могла. А куда же тогда переменная-то исчезла?

Ничего никуда не исчезло. Просто произошло перераспределение памяти и теперь ячейка с этим адресом может содержать уже что-то другое. Например, она отведена уже под совсем другую переменную. Или ни под что не отведена, а находится в НЕвыделенной области динамической памяти, или в НЕактивной части стека.

И поэтому, хотя адрес этой ячейки в указателе и не изменился, но обращаться по нему уже нельзя. А если мы по нему все же обратимся, то получим либо какое-то непредсказуемое значение (мусор, попросту говоря), либо сообщение об ошибке.

Жил Иван Иваныч по адресу $00CA3DF1, но потом, увы, умер. А по этому адресу либо уже никто не живет (дом сломали), либо живет кто-то другой. И письмо по старому адресу либо попадет к кому-то неизвестному, либо вернется с ошибкой "неверный адрес".

Вот и в компьютере - то же самое.
:о)


Piter   (2004-10-19 23:18:00) [12]

Zeqfreed ©   (19.10.04 22:11) [4]
Юрий Зотов меня прямо таки удивляет наглядностью своих примеров!


ну а чего ты хотел то - бывший педагог :)


begin...end   (2004-10-19 22:38:00) [13]

Вдогонку: только не adress, а Addr()


begin...end   (2004-10-19 22:37:00) [14]


> [5] Falcon(TFSoft) ©   (19.10.04 22:30)


> P := pinteger(i);  // Теперь P хранит адрес переменной I???

Нет! Теберь 4 байта в памяти, которые раньше интерпретировались как целое число, теперь рассматриваются как указатель! Но указатель неверен!

> P := adress(i);  //?? или вот так

Можно!


jack128   (2004-10-19 22:36:00) [15]

Falcon(TFSoft) ©   (19.10.04 22:30) [5]
P := pinteger(i);  // Теперь P хранит адрес переменной I???

нет. Будет явное преобразование типов, в P будет храниться -6. И указывать этот указатель на число, хранящееся в $FFFFFFFA ячейке памяти. ($FFFFFFFA - так представляется число -6)
Falcon(TFSoft) ©   (19.10.04 22:30) [5]
P := adress(i);  //?? или вот так
а что это такое?? Есть функция addr - эквивалент оператора @


Falcon(TFSoft)   (2004-10-19 22:30:00) [16]

Спасибо всем за ответы.

Юрию Зотову:

var
I: integer;  // целое число в памяти
P: ^integer; // адрес целого числа в памяти
begin
P := @I;  // Теперь P хранит адрес переменной I
end;


а будет ли одно и тоже если


var
I: integer;  
P: pinteger; // помоему уже определённый тип
begin
I := -6;
P := pinteger(i);  // Теперь P хранит адрес переменной I???
P := adress(i);  //?? или вот так
end;


И последний вопрос на эту тему...
если сделать глобальный указатель, который будет уаказывать на адресс локальной переменной в функции, то после завершения времени жизни это переменной на что будет указывать этот указатель?

Зарание спасибо!


Zeqfreed   (2004-10-19 22:11:00) [17]

Юрий Зотов меня прямо таки удивляет наглядностью своих примеров!


begin...end   (2004-10-19 22:08:00) [18]


> Falcon(TFSoft) ©   (19.10.04 21:55)

Если P - указатель, то P^ даст значение, размещённое по адресу, на которое он указывает.
Если A - переменная, то @A даст адрес этой переменной (указатель на неё).


Юрий Зотов   (2004-10-19 22:07:00) [19]


var
 I: integer;  // целое число в памяти
 P: ^integer; // адрес целого числа в памяти
begin
 P := @I;  // Теперь P хранит адрес переменной I
 I := -6;  // Теперь P осталось прежним, а P^ будет равно -6
 P^ := 8;  // Теперь P осталось прежним, а I стало равно 8
 P := nil; // Теперь I осталось равно 8, а P^ даст ошибку.
end;


Gero   (2004-10-19 21:56:00) [20]

В хелпе что-то не разобрал?


Наверх

Титульная страница Поиск, карта сайта Написать письмо