![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Длина строки [D7, WinXP]
Dmitry_177 © (2007-05-20 01:11:00)При использовании 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);
чтобы в памяти она не занимала места?
Anatoly Podgoretsky (2007-06-04 13:58:00) [1]> Однокамушкин (04.06.2007 13:34:32) [32]
А если взять более старые версии Дельфи, то и все 12
Однокамушкин (2007-06-04 13:34:00) [2]
> Reindeer Moss Eater © (04.06.07 12:48) [31]
Если считать и эти байты, то не +4, а +8... там по отрицательному смещению ещё длина строки хранится...
Reindeer Moss Eater (2007-06-04 12:48:00) [3]> Когда выполняется SetLength(str, MAX_PATH), для str резервируется
> MAX_PATH+1 байт. Лишний байт - это как раз для нулевого
> символа в конце, который при обычной работе со stringом
> добавляется автоматически...
Вообще то нет, если говорить не о длине, а именно о резервируемых байтах.
Резервируется 4 + MAX_PATH + 1 байтов.
Первые четыре - для подсчтета ссылок.
ANB (2007-06-04 12:38:00) [4]
> Всяко же бывает, пожалуй.
Как правило, функцию апи мона вызвать в двух режимах :
в первом только определяется длинна буфера, мы его можем создать
во втором собственно заполняется буфер. Редкие исключения - это когда буфер сразу ограничен константой типа max_path.
KSergey (2007-06-04 12:08:00) [5]По поводу вопросов и рассужденйи автора топика хотелось бы сделать замечания:
1) В большенстве случаев в описании функции явно оговаривается входит завершающий нуль в указываемую длину буфера или нет.
2) А почему рассматривается только MAX_PATH в разрезе "вообще любых" API функции? Всяко же бывает, пожалуй.
deyxv (2007-06-03 15:08:00) [6]Удалено модератором
Dmitry_177 (2007-05-23 02:58:00) [7]Удалено модератором
Dmitry_177 (2007-05-21 20:11:00) [8]http://www.delphimaster.ru/cgi-bin/forum.pl?id=1176447569&n=5
Сергей М. (2007-05-21 17:18:00) [9]
> 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 17:05:00) [10]Если строк будет MAX_PATH, и в функцию передать длину MAX_PATH, и если функция передаст строку длинной MAX_PATH символов, то получается что строка окажется без нулевого символа?
clickmaker (2007-05-21 16:52:00) [11]
> Т.е. если я задам SetLength(str, MAX_PATH) то строка будет
> длиной MAX_PATH + 1?
нет, строка будет именно MAX_PATH
Johnmen (2007-05-21 16:51:00) [12]
> Однокамушкин (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.
Dmitry_177 (2007-05-21 16:33:00) [13]
Однокамушкин (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?
Dmitry_177 (2007-05-21 12:40:00) [14]Т.е. значит и в SetLength и в саму API функцию передавать MAX_PATH.. Я это почему спросил вообще, чтобы избежать переполнения буфера, т.е. чтобы не записывался нуль за пределом MAX_PATH..
Dmitry_177 (2007-05-21 12:40:00) [15]Т.е. значит и в SetLength и в саму API функцию передавать MAX_PATH.. Я это почему спросил вообще, чтобы избежать переполнения буфера, т.е. чтобы не записывался нуль за пределом MAX_PATH..
clickmaker (2007-05-21 12:22:00) [16]
> [17] umbra © (21.05.07 12:01)
если у функции аргумент типа pchar, то обязана поставить. Иначе это баг
umbra (2007-05-21 12:01:00) [17]
> А потом эта функция сама поставит ноль
это как раз не факт, по-моему. Зависит от АПИ.
Однокамушкин (2007-05-21 11:51:00) [18]
> umbra © (21.05.07 11:29) [15]
>
> > В общем, для надежности, после SetLength(str, MAX_PATH);
> строку надо заполнить символами #0.
А зачем? API-функции, которая будет писать в этот буфер, всё равно, есть ли там нули или нет и где они стоят... А потом эта функция сама поставит ноль, куда нужно, и StrLen нормально отработает...
umbra (2007-05-21 11:29:00) [19]
> SetLength(str, MAX_PATH);
при этом память, выделенная под строку никак не инициализируется, т.е. там валяется мусор.
> SetLength(str, StrLen(PChar(str)));
Поскольку строка послеSetLength(str, MAX_PATH);заполнена мусором, то неизвестно, где там впервые встретится #0, а именно его и ищет StrLen для определения результата.
В общем, для надежности, послеSetLength(str, MAX_PATH);строку надо заполнить символами #0.
Однокамушкин (2007-05-21 10:49:00) [20]Когда выполняется SetLength(str, MAX_PATH), для str резервируется MAX_PATH+1 байт. Лишний байт - это как раз для нулевого символа в конце, который при обычной работе со stringом добавляется автоматически...