Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.12;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.032 c
2-1184610803
Knob
2007-07-16 22:33
2007.08.12
Определение координат ячейки в Excel


2-1184346134
WFS
2007-07-13 21:02
2007.08.12
Как поменять название поля в базе данных (программным образом)?


2-1184347870
nord489
2007-07-13 21:31
2007.08.12
Работа с файлами


2-1183128441
TIF
2007-06-29 18:47
2007.08.12
DLL &amp; PNG, GIF, JPG и т. п.


3-1177562304
O.O
2007-04-26 08:38
2007.08.12
Динамические структуры