Форум: "Основная";
Текущий архив: 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.049 c