![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Length(string(P)) - маразм?
SkyQuake © (2002-07-09 10:09:00)Преамбула:
var P:Pointer;
...
//Надо определить размер данных, на которые указывает P
Size:=Length(string(P));
Товарищи!
В условиях жёсткой нехватки времени была поставлена цель в ближайшую пятидневку найти таки об"ём данных на которые указывает P. Попытки связаные с SizeOf не увенчались успехом. И никто не знал почему ЭТО работает, но работает безотказно.
Eugene Lachinov (2002-07-09 10:58:00) [1]Цифры взяты из Source\Rtl\Sys\getmem.inc, только вот для каких Delphi не помню (5 или 6), может что-то поменялось
Dimka Maslov (2002-07-09 10:44:00) [2]Это работает поскольку сначала выделяется память под строку типа string, а потом определяется длина строки. Для строк типа string длина располагается четырьмя байтами младше первого её символа.
Другой вопрос а как определяется длина блока, на который указывает P. В твоём случае указатель P представляется как PChar и программа ищет первый нулевой символ в блоке данных. Найдя его она вычисляет разность двух указателей, определяя таким образом длину блока. (функция StrLen)
Если же память выделена динамически вручную, то и тут есть способы определить её размер. Любой менеджер динамической памяти имеет таблицу, в которой содержатся все указатели на выделенные им блоки памяти. К примеру для блоков памяти выделенных LocalAlloc есть функция LocalSize, GlobalAlloc - GlobalSize, HeapAlloc - HeapSize и т.д. Поскольку динамическое выделение памяти GetMem, New, AllocMem - это скрытые вызовы WinAPI достаточно определить какой именно сиситемной функцией было произведено выделение памяти.
Особый случай, не поддающийся определению размера - это прямое присваивание указателей на локальные или глобальные переменные. Тут длина блока будет зависеть от типа пременной на которую ссылается указатель и определить её при выполнении программу нельзя. Надо следить за размерами на этапе написания кода.
Sasha9 (2002-07-09 10:41:00) [3]2Eugene Lachinov
а можно по подробнее откуда эти цифры?
Eugene Lachinov (2002-07-09 10:39:00) [4]function GetMemSize(P : Pointer) : Integer;
begin
Result := (PLongInt(PChar(p)-4)^ and not $80000003) - 4
end;
MBo (2002-07-09 10:35:00) [5]>Игорь Шевченко
несколько раз уже говорили- не верит ;(
Игорь Шевченко (2002-07-09 10:31:00) [6]
> var P:Pointer;
> ...
> //Надо определить размер данных, на которые указывает P
> Size:=Length(string(P));
Это - неправильный способ.
Fiend (2002-07-09 10:13:00) [7]Оно то работает, но на мой взгляд не оптимально.
Если Р указывает на PChar, то пользуйся StrLen(P)