Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];

Вниз

Length(string(P)) - маразм?   Найти похожие ветки 

 
SkyQuake   (2002-07-09 10:09) [0]

Преамбула:
var P:Pointer;
...
//Надо определить размер данных, на которые указывает P
Size:=Length(string(P));

Товарищи!
В условиях жёсткой нехватки времени была поставлена цель в ближайшую пятидневку найти таки об"ём данных на которые указывает P. Попытки связаные с SizeOf не увенчались успехом. И никто не знал почему ЭТО работает, но работает безотказно.


 
Fiend   (2002-07-09 10:13) [1]

Оно то работает, но на мой взгляд не оптимально.

Если Р указывает на PChar, то пользуйся StrLen(P)


 
Игорь Шевченко   (2002-07-09 10:31) [2]


> var P:Pointer;
> ...
> //Надо определить размер данных, на которые указывает P
> Size:=Length(string(P));


Это - неправильный способ.


 
MBo   (2002-07-09 10:35) [3]

>Игорь Шевченко
несколько раз уже говорили- не верит ;(


 
Eugene Lachinov   (2002-07-09 10:39) [4]

function GetMemSize(P : Pointer) : Integer;
begin
Result := (PLongInt(PChar(p)-4)^ and not $80000003) - 4
end;


 
Sasha9   (2002-07-09 10:41) [5]

2Eugene Lachinov
а можно по подробнее откуда эти цифры?


 
Dimka Maslov   (2002-07-09 10:44) [6]

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

Другой вопрос а как определяется длина блока, на который указывает P. В твоём случае указатель P представляется как PChar и программа ищет первый нулевой символ в блоке данных. Найдя его она вычисляет разность двух указателей, определяя таким образом длину блока. (функция StrLen)

Если же память выделена динамически вручную, то и тут есть способы определить её размер. Любой менеджер динамической памяти имеет таблицу, в которой содержатся все указатели на выделенные им блоки памяти. К примеру для блоков памяти выделенных LocalAlloc есть функция LocalSize, GlobalAlloc - GlobalSize, HeapAlloc - HeapSize и т.д. Поскольку динамическое выделение памяти GetMem, New, AllocMem - это скрытые вызовы WinAPI достаточно определить какой именно сиситемной функцией было произведено выделение памяти.

Особый случай, не поддающийся определению размера - это прямое присваивание указателей на локальные или глобальные переменные. Тут длина блока будет зависеть от типа пременной на которую ссылается указатель и определить её при выполнении программу нельзя. Надо следить за размерами на этапе написания кода.



 
Eugene Lachinov   (2002-07-09 10:58) [7]

Цифры взяты из Source\Rtl\Sys\getmem.inc, только вот для каких Delphi не помню (5 или 6), может что-то поменялось



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.005 c
1-70741
TTCustomDelphiMaster
2002-07-09 11:48
2002.07.22
Кто хавает память?


7-70936
_TOLTEC
2002-04-25 15:10
2002.07.22
MacAddress


3-70674
_dron_
2002-07-02 16:11
2002.07.22
Фильтрация в ADODataSet


1-70775
jen_bond
2002-07-09 11:38
2002.07.22
Изменение размера компонента


1-70751
Loco
2002-07-07 17:40
2002.07.22
Исключения





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский