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

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

var-Параметры_процедур - указатели. То ли лыжи не едут, .... [D7, XP]


Страницы:   1 2

Cobalt ©   (2007-08-29 16:31:00) 

Подскажите, как указать, что процедуре можно передать любой указатель, а то если указать просто Pointer, то она требует обязательно привести к Pointer

procedure ReFillPointer(var p: pointer; len: Cardinal; b: Byte=0);
----
 PSecurityDescriptor = ^TSecurityDescriptor;
var
Desc: PSecurityDescriptor;

----
так - ругается
ReFillPointer(@Desc,len,0);
Types of actual and formal var parameters must be identical

а так - нет:
ReFillPointer(Pointer(Desc),len,0);

Но чёт у меня сомнения насчёт второго варианта...

P.S.
А поставил procedure ReFillPointer(var p: PSecurityDescriptor; len: Cardinal; b: Byte=0);- и не требуется приведение.

Как бы вообще обойтись без приведения?

ей даже {$T-} пофиг...

Чё-то нифига не пойму :(


Anatoly Podgoretsky   (2007-08-30 13:51:00) [1]

> KSergey  (30.08.2007 13:44:25)  [25]

Но не переменная и поэтому значение некуда присваивать


Инс   (2007-08-30 13:45:00) [2]


> ЮЗ все же объяснил уже.

ЮЗ объяснил не совсем все. В частности вот это:

> А вот так все должно прокатывать:
> ReFillPointer(Desc, len, 0);

не верно.


KSergey   (2007-08-30 13:44:00) [3]

В дополнение к > KSergey ©   (30.08.07 13:42) [24]

хотя в MyProc(L + 5) передаваемый параметр - типа Integer.

Ошибка будет, наверное, другая при компиляции этого примера, но смысл - по-моему как раз.


KSergey   (2007-08-30 13:42:00) [4]

По исходному вопросу.
Это лыжи не едут, однозначно :) ЮЗ все же объяснил уже.

В var параметр можно передавать только переменнуюи ничего более.
Приведенный пример - тоже самое, что нельзя делать, например, так:

procedure MyProc(var i: Integer);
beain
...
end;
.....

var
  L: Integer;
...
MyProc(L + 5);


Однако можно так:

var
  L: Integer;
...
L := L + 5;
MyProc(L);


Ферштейн?


Инс   (2007-08-30 13:40:00) [5]


> мдя... а я всегда думал, что указатель и адрес это одно
> и тоже :-)

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


wp2   (2007-08-30 13:30:00) [6]

мдя... а я всегда думал, что указатель и адрес это одно и тоже :-)

Правда никогда бы этого не утверждал.


Инс   (2007-08-29 20:44:00) [7]


> [20] DVM ©   (29.08.07 20:41)


Вы тоже видимо в [8] с Dispose перепутали...


DVM   (2007-08-29 20:41:00) [8]


> Вы с каким утверждением спорите? :) Что непонятно?

Я не спорю. Все верно. Не заметил слово "типизированный".


Инс   (2007-08-29 20:37:00) [9]


> [17] DVM ©   (29.08.07 20:35)

Не скорее всего, а точно. Я же написал в [12], что Dispose нужно передавать типизированный указатель. А FreeMem - по барабану. Вы с каким утверждением спорите? :) Что непонятно? Могу попытаться разъяснить


Инс   (2007-08-29 20:35:00) [10]


> Собственно вопрос - откуда несовместимость???

Из-за ключевого слова var. Тип актуального и формального параметра должны быть идентичны, об этом вам сообщение об ошибке и утверждает. C Integer и Cardinal тоже не прокатит, не только в Pointer-ах проблема.


DVM   (2007-08-29 20:35:00) [11]


> А Dispose финализирует их и освобождает память.

Если Dispose() передать нетипизированный указатель на структуру из [13], то тоже будет утечка скорее всего.


Инс   (2007-08-29 20:30:00) [12]

Кстати, не имеет значения, типизированный или нетипизированный указатель передается в FreeMem. Он все равно освобождает память "тупо".


Инс   (2007-08-29 20:27:00) [13]


> Если в процедуру передается нетипизированный указатель на
> вот такую запись и потом внутри процедуры происходит FreeMem,
> то имхо компилятор не может построить внутри процедуры код,
> который корректно освободит память под строки.

Естественно. FreeMem - это "тупое" освобождение памяти. FreeMem не умеет работать со сложными структурами данных, содержащих длинные строки, динмассивы и пр. Для таких записей нужно выделять память с помощью New, а освобождать - Dispose. New не только выделяет память под структуру, но и инициализирует поля сложных типов. А Dispose финализирует их и освобождает память.


Инс   (2007-08-29 20:23:00) [14]


> именно этого-то и хотел


Вы хотели передать адрес указателя??? Вот смотрите, у вас есть указатель, значение которого $XXXXXXXX. Сама переменная указательного типа находится по адресу $YYYYYYYY скажем, в стеке, если это локальная переменная. Так вот, вызовом
ReFillPointer(@Desc,len,0);
вы пытаетесь передать в процедуру именно $YYYYYYYY, а вам скорее всего нужно $XXXXXXXX. Еще раз перечитайте [5].


> А поставил procedure ReFillPointer(var p: PSecurityDescriptor; len: Cardinal; b: > Byte=0); - и не требуется приведение.

Уверен, что если "собаку" в вызове оставили, то не работает, компилятор не пропустит. Так как var-параметр должен быть именно переменной, а не значением (адрес переменной - это значение). var уберете - и с "собакой" компилятор пропустит.


DVM   (2007-08-29 20:11:00) [15]


> Cobalt прав. Второй параметр у FreeMem оставлен только для
> совместимости со старым кодом и на самом деле не используется.
>

Если в процедуру передается нетипизированный указатель на вот такую запись и потом внутри процедуры происходит FreeMem, то имхо компилятор не может построить внутри процедуры код, который корректно освободит память под строки.

type
 TMyRec = record
    s1: string;
    s2: string;
 end;
 PMyRec = ^TMyRec;


Инс   (2007-08-29 19:59:00) [16]


> [9] umbra ©   (29.08.07 17:35)


Cobalt прав. Второй параметр у FreeMem оставлен только для совместимости со старым кодом и на самом деле не используется. Размер памяти, который нужно освободить, менеджер всегда определяет опираясь на свои записи.

Скорее всего Вы путаете с процедурой Dispose, которой действительно нужно передавать типизированный указатель, иначе память будет освобождена некорректно.


Cobalt   (2007-08-29 19:31:00) [17]

Собственно вопрос - откуда несовместимость???
Почему конкретный указательный тип несовместим с Pointer в параметре процедуры?


Cobalt   (2007-08-29 19:06:00) [18]

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


umbra   (2007-08-29 17:35:00) [19]


> FreeMem(p);

у FreeMem может быть 2 параметра. Второй - размер области памяти, на которую указывает первый параметр. Если передавать первым нетипизированный указатель, то как функция узнает, сколько памяти освобождать?


DVM   (2007-08-29 17:33:00) [20]


> Cobalt ©   (29.08.07 17:25) [6]


> FreeMem(p);

Утечек не получится? Если указатель будет нетипизированным.


Страницы:   1 2

Наверх

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