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

Вниз

Длина строки   Найти похожие ветки 

 
Dmitry_177   (2007-05-20 01:11) [0]

При использовании API функций часто бывает пользуются такой схемой:

var
str: string;
...

SetLength(str, MAX_PATH);
...какаянибудь API функция в которую передается PChar(str)
str := PChar(str);  или SetLength(str, StrLen(PChar(str)));

Так вот я хотел бы спросить, как потом правильней будет укоротить спроку, так:

str := PChar(str);

или так:

SetLength(str, StrLen(PChar(str)));


И еще, потом после использования переменной str, т.е. когда она стала ненужной, нужно ли ей задавать нулевой размер, т.е так:

SetLength(str, 0);

чтобы в памяти она не занимала места?


 
Германн ©   (2007-05-20 02:01) [1]


> Dmitry_177   (20.05.07 01:11)
>
> При использовании API функций часто бывает пользуются такой
> схемой:
>

При использовании API-функций, как правило, рекомендуется обращать внимание на размер возвращаемых данных, которые как правило присутствуют в API-шных функциях.


 
Германн ©   (2007-05-20 02:13) [2]

<offtop>
Классная очепятка получилась! Is"nt it?
</offtop>
Ей-богу всё вышло случайно.


 
Anatoly Podgoretsky ©   (2007-05-20 02:28) [3]

> Германн  (20.05.2007 02:01:01)  [1]

Я бы не стал, поскольку нет единства, иногда это длина строки, а иногда +1
А вот PChar(S) гарантировано.


 
Anatoly Podgoretsky ©   (2007-05-20 02:30) [4]

> Dmitry_177  (20.05.2007 01:11:00)  [0]

Можно так SetLength(str, 0), но можно и str := nil или str := ""
Результат одинаков, а можно и не делать, при выходе за пределы видимости переменная сама обнулится


 
Германн ©   (2007-05-20 02:42) [5]


> Anatoly Podgoretsky ©   (20.05.07 02:28) [3]
>
> > Германн  (20.05.2007 02:01:01)  [1]
>
> Я бы не стал, поскольку нет единства, иногда это длина строки,
>  а иногда +1
> А вот PChar(S) гарантировано.

И я бы тоже не стал, но "+1 ", имхо гарантирует ну хоть что-то. Лишний выделенный байт в массиве, врядли сможет реально помешать программе.
:)


 
Dmitry_177   (2007-05-20 08:35) [6]

Так все же str := PChar(str);  или SetLength(str, StrLen(PChar(str)));?

А если будет такая схема:

SetLength(str, MAX_PATH);
...какаянибудь API функция в которую передается PChar(str)
str := PChar(str);  или SetLength(str, StrLen(PChar(str)));

а потом в этой же функции или процедуре нужно str присвоить какую-нибудь строку

str := "vbrftgbtrbrtntrentrnrthne";

так вот если присваемая строка будет длиннее чем бы задали SetLength-ем, она обрежется? Как сделать из str опять обычный string?


 
Однокамушкин   (2007-05-20 10:14) [7]


> Как сделать из str опять обычный string?


Она никогда не перестаёт быть обычным stringом... и ничего обрезаться не будет. Как только строка меняет значение, о том, что там когда-то давно ей делали SetLength, она сразу забывает...


 
Anatoly Podgoretsky ©   (2007-05-20 12:09) [8]

> Германн  (20.05.2007 02:42:05)  [5]

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


 
Anatoly Podgoretsky ©   (2007-05-20 12:10) [9]

> Dmitry_177  (20.05.2007 08:35:06)  [6]

Она не обрежется, она переопределится.
А вот если такое произойдет в АПИ, то я тебе не завидую.


 
Anatoly Podgoretsky ©   (2007-05-20 12:12) [10]

> Однокамушкин  (20.05.2007 10:14:07)  [7]

При возврате из АПИ перестает, поскольку АПИ ничего не знает о структуре строк Паскаля, ему глубоко плевать на это, отсюда или недостоверная информация в структуре или что обычно AV


 
Однокамушкин   (2007-05-20 21:08) [11]


> Anatoly Podgoretsky ©   (20.05.07 12:12) [10]

Сама переменная str не перестаёт быть переменной типа string... просто APIшные функции работают с тем же буфером в обход этой переменной...


 
Dmitry_177   (2007-05-21 10:43) [12]

У меня еще вопрос.. делаем мы так:

SetLength(str, MAX_PATH);
...какаянибудь API функция в которую передается PChar(str), а длинну строки MAX_PATH или MAX_PATH + 1?

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


 
Сергей М. ©   (2007-05-21 10:48) [13]


> Dmitry_177   (21.05.07 10:43) [12]


MAX_PATH будет вполне достаточно.


 
Однокамушкин   (2007-05-21 10:49) [14]

Когда выполняется SetLength(str, MAX_PATH), для str резервируется MAX_PATH+1 байт. Лишний байт - это как раз для нулевого символа в конце, который при обычной работе со stringом добавляется автоматически...


 
umbra ©   (2007-05-21 11:29) [15]


> SetLength(str, MAX_PATH);

при этом память, выделенная под строку никак не инициализируется, т.е. там валяется мусор.


> SetLength(str, StrLen(PChar(str)));

Поскольку строка после SetLength(str, MAX_PATH); заполнена мусором, то неизвестно, где там впервые встретится #0, а именно его и ищет StrLen для определения результата.
В общем, для надежности, после SetLength(str, MAX_PATH); строку надо заполнить символами #0.


 
Однокамушкин   (2007-05-21 11:51) [16]


> umbra ©   (21.05.07 11:29) [15]
>
> > В общем, для надежности, после SetLength(str, MAX_PATH);
>  строку надо заполнить символами #0.


А зачем? API-функции, которая будет писать в этот буфер, всё равно, есть ли там нули или нет и где они стоят... А потом эта функция сама поставит ноль, куда нужно, и StrLen нормально отработает...


 
umbra ©   (2007-05-21 12:01) [17]


> А потом эта функция сама поставит ноль

это как раз не факт, по-моему. Зависит от АПИ.


 
clickmaker ©   (2007-05-21 12:22) [18]


> [17] umbra ©   (21.05.07 12:01)

если у функции аргумент типа pchar, то обязана поставить. Иначе это баг


 
Dmitry_177   (2007-05-21 12:40) [19]

Т.е. значит и в SetLength и в саму API функцию передавать MAX_PATH.. Я это почему спросил вообще, чтобы избежать переполнения буфера, т.е. чтобы не записывался нуль за пределом MAX_PATH..


 
Dmitry_177   (2007-05-21 12:40) [20]

Т.е. значит и в SetLength и в саму API функцию передавать MAX_PATH.. Я это почему спросил вообще, чтобы избежать переполнения буфера, т.е. чтобы не записывался нуль за пределом MAX_PATH..


 
Dmitry_177   (2007-05-21 16:33) [21]


Однокамушкин   (21.05.07 10:49) [14]
Когда выполняется SetLength(str, MAX_PATH), для str резервируется MAX_PATH+1 байт. Лишний байт - это как раз для нулевого символа в конце, который при обычной работе со stringом добавляется автоматически...


Т.е. если я задам SetLength(str, MAX_PATH) то строка будет длиной MAX_PATH + 1? И если API функция запишет все MAX_PATH символов в строку то все будет ОК? т.е. нулевой символ запишется последним т.е. MAX_PATH + 1?


 
Johnmen ©   (2007-05-21 16:51) [22]


> Однокамушкин   (21.05.07 10:49) [14]
> Когда выполняется SetLength(str, MAX_PATH), для str резервируется
> MAX_PATH+1 байт. Лишний байт - это как раз для нулевого
> символа в конце, который при обычной работе со stringом
> добавляется автоматически...

Это не совсем так.
Выделяется память, кратная 4 байтам, не меньшая, чем [<длина строки>+1+4+4]  байт.

> Dmitry_177   (21.05.07 16:33) [21]
> ..Т.е. если я задам SetLength(str, MAX_PATH) то строка будет длиной MAX_PATH + 1?

Строка будет длиной MAX_PATH.


 
clickmaker ©   (2007-05-21 16:52) [23]


> Т.е. если я задам SetLength(str, MAX_PATH) то строка будет
> длиной MAX_PATH + 1?

нет, строка будет именно MAX_PATH


 
Dmitry_177   (2007-05-21 17:05) [24]

Если строк будет MAX_PATH, и в функцию передать длину MAX_PATH, и если функция передаст строку длинной MAX_PATH символов, то получается что строка окажется без нулевого символа?


 
Сергей М. ©   (2007-05-21 17:18) [25]


> Dmitry_177   (21.05.07 17:05) [24]


> получается что строка окажется без нулевого символа?


Почему без нулевого-то ?
Он всегда есть после SetLength(), если ты его ничем не испортил.

Пусть, к примеру, MAX_PATH = 3.

Пусть ты вызвал SetLength(s, MAX_PATH), тогда содержимое байт в буфере строки стало

XX XX XX 00

где XX - неопределенное значение

Пусть теперь ты вызвал некую API-функцию, возвращающую MAX_PATH символов в указанный строковый буфер переменной s

Тогда после возврата из ф-ции новое содержимое буфера строки будет выглядеть так:

AA BB CC 00


 
Dmitry_177   (2007-05-21 20:11) [26]

http://delphimaster.net/view/4-1176447569/


 
Dmitry_177   (2007-05-23 02:58) [27]

Удалено модератором


 
deyxv   (2007-06-03 15:08) [28]

Удалено модератором


 
KSergey ©   (2007-06-04 12:08) [29]

По поводу вопросов и рассужденйи автора топика хотелось бы сделать замечания:
1) В большенстве случаев в описании функции явно оговаривается входит завершающий нуль в указываемую длину буфера или нет.
2) А почему рассматривается только MAX_PATH в разрезе "вообще любых" API функции? Всяко же бывает, пожалуй.


 
ANB ©   (2007-06-04 12:38) [30]


> Всяко же бывает, пожалуй.

Как правило, функцию апи мона вызвать в двух режимах :
в первом только определяется длинна буфера, мы его можем создать
во втором собственно заполняется буфер. Редкие исключения - это когда буфер сразу ограничен константой типа max_path.


 
Reindeer Moss Eater ©   (2007-06-04 12:48) [31]

> Когда выполняется SetLength(str, MAX_PATH), для str резервируется
> MAX_PATH+1 байт. Лишний байт - это как раз для нулевого
> символа в конце, который при обычной работе со stringом
> добавляется автоматически...


Вообще то нет, если говорить не о длине, а именно о резервируемых байтах.
Резервируется 4 + MAX_PATH + 1 байтов.
Первые четыре - для подсчтета ссылок.


 
Однокамушкин   (2007-06-04 13:34) [32]


> Reindeer Moss Eater ©   (04.06.07 12:48) [31]

Если считать и эти байты, то не +4, а +8... там по отрицательному смещению ещё длина строки хранится...


 
Anatoly Podgoretsky ©   (2007-06-04 13:58) [33]

> Однокамушкин  (04.06.2007 13:34:32)  [32]

А если взять более старые версии Дельфи, то и все 12



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

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

Наверх




Память: 0.56 MB
Время: 0.054 c
11-1166902282
Trible
2006-12-23 22:31
2007.08.12
Как уничтожить форму с компонентами


3-1176383248
ZevSS
2007-04-12 17:07
2007.08.12
Репликация БД и глобальный поиск


2-1184090570
Евгений Р.
2007-07-10 22:02
2007.08.12
Перемещение по DrawGrid


1-1181139901
Terr
2007-06-06 18:25
2007.08.12
Проблема с выбором драйвера базы данных


2-1184178258
AIK
2007-07-11 22:24
2007.08.12
Модить папки





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский