Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Длина строки 
:(
    Опции темы
Dmitry_177
Дата 20.5.2007, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



При использовании 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);


чтобы в памяти она не занимала места?
PM MAIL   Вверх
Poseidon
Дата 20.5.2007, 02:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 53
Всего: 133



Цитата(Dmitry_177 @  20.5.2007,  00:13 Найти цитируемый пост)
И еще, потом после использования переменной str, т.е. когда она стала ненужной, нужно ли ей задавать нулевой размер
Нет. Переменная str занимает место сразу после обявления (var), т.к. она string. И даже если "длина" переменной будет равна 0, она все-равно будет занимать место в памяти.
Высвободится память сразу после выполнения функции или процедуры, в каторой обьявлена переменная.

Цитата(Dmitry_177 @  20.5.2007,  00:13 Найти цитируемый пост)
Так вот я хотел бы спросить, как потом правильней будет укоротить спроку
Правильнее будет SetLength(str, StrLen(PChar(str))); т.к. конвертирование форматов для форматирования данных - не лучший вариант.


Это сообщение отредактировал(а) Poseidon - 20.5.2007, 02:39


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Dmitry_177
Дата 20.5.2007, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



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

Код

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


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

str := 'vbrftgbtrbrtntrentrnrthne';

так вот если присваемая строка будет длиннее чем мы задали SetLength-ем, она обрежется? ИМХО вообще наверно переполнение будет.. Как сделать из str опять обычный string?
PM MAIL   Вверх
MetalFan
Дата 20.5.2007, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



чаще всего функции WinApi возвращают длину возвращаемой строки...


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Snowy
Дата 20.5.2007, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Цитата(Dmitry_177 @  20.5.2007,  00:13 Найти цитируемый пост)
ак вот я хотел бы спросить, как потом правильней будет укоротить спроку, так:
str := PChar(str);
или так:
SetLength(str, StrLen(PChar(str)));
str := PChar(str);
Второе просто производит больше ненужных действий.

Цитата(Dmitry_177 @  20.5.2007,  00:13 Найти цитируемый пост)
И еще, потом после использования переменной str, т.е. когда она стала ненужной, нужно ли ей задавать нулевой размер, т.е так:
SetLength(str, 0);
чтобы в памяти она не занимала места?
Нет не нужно.
При выходе за пределы видимости вся память, занимаемая строкой, будет освобождена автоматически.

Цитата(Dmitry_177 @  20.5.2007,  07:49 Найти цитируемый пост)
а потом в этой же функции или процедуре нужно str присвоить какую-нибудь строкуstr := 'vbrftgbtrbrtntrentrnrthne';так вот если присваемая строка будет длиннее чем мы задали SetLength-ем, она обрежется?
Строка автоматически изменит свой размер.
При прямом присвоении уже не имеет значения, что там ей раньше присваивалось и какой размер устанавливался.
PM MAIL   Вверх
Alexeis
Дата 20.5.2007, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Dmitry_177, передавать в API лучше всего строку типа 
  str : array[0..size] of char; с нулем на конце.

При конвертировании String в PChar нарушается работа подсчета ссылок в строках типа String. В результате легко испортить данные по выходу из процедуры. 

Если размер строки неизвестен, то можно воспользоваться следующим способом.
Код

procedure TForm1.FormCreate(Sender: TObject);
type
  longstr   = array[0..High(Integer) - 1] of char;
  plongstr = ^longstr;

var
  myStr : plongstr;
  strlen : DWORD;
  s    : String;
begin
   s := 'text' + ' что-то еще' + ' и еще что-то';

   strlen := Length(s) + 1;
   GetMem(myStr, strlen);
   move(s[1], myStr^, strlen);
   SetWindowText(Form1.Handle, PChar(myStr));
...


  Каждый остается со своей строкой. Делфийская прога с делфийской, а винда с сишной строкой. Только прийдеться уже вручную освобождать память строки myStr, тогда  когда она уже будет не нужна.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dmitry_177
Дата 21.5.2007, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



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

Код

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


ведь строка же должна завержаться нулевым символом, а это значит еще один символ.. Так вот чтобы правильно все было сколько нужно задать в SetLength и в какойнибудь API на примере с MAX_PATH?
PM MAIL   Вверх
Alexeis
Дата 21.5.2007, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Dmitry_177, ansi строки всегда завершаются нулем. Это делает компилятор за нас. Потому они совместимы с PChar.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dmitry_177
Дата 21.5.2007, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Я это почему спросил вообще, чтобы избежать переполнения буфера, т.е. чтобы не записывался нуль за пределом MAX_PATH..
PM MAIL   Вверх
Dmitry_177
Дата 21.5.2007, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Я где-то слышал что, когда выполняется SetLength(str, MAX_PATH), для str резервируется MAX_PATH+1 байт. Лишний байт - это как раз для нулевого символа в конце, который при обычной работе со stringом добавляется автоматически.. Правда ли это?
PM MAIL   Вверх
Alexeis
Дата 21.5.2007, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Alexeis @  21.5.2007,  09:56 Найти цитируемый пост)
ansi строки всегда завершаются нулем. Это делает компилятор за нас. 




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dmitry_177
Дата 21.5.2007, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 22.9.2006

Репутация: нет
Всего: нет



Alexeis, да, но если задаем размер строки MAX_PATH символов, и API функция передаст в нее ровно MAX_PATH символов.. получится так что нулевой символ туда уже не запишется.. Вот я и спрашиваю нужноли MAX_PATH +1 делать? И еще: Я где-то слышал что, когда выполняется SetLength(str, MAX_PATH), для str резервируется MAX_PATH+1 байт. Лишний байт - это как раз для нулевого символа в конце, который при обычной работе со stringом добавляется автоматически.. Правда ли это?
PM MAIL   Вверх
Alexeis
Дата 21.5.2007, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Dmitry_177, для строки резервируется length(s) + 9 байт, 4 для счетчика ссылок 4 для длинны и 1 для завершающего нуля.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1080 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.