![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
var-Параметры_процедур - указатели. То ли лыжи не едут, .... [D7, XP]
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);
Утечек не получится? Если указатель будет нетипизированным.