std::string as std::vector
От: Аноним  
Дата: 28.03.05 12:15
Оценка:
Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо
Re: std::string as std::vector
От: Vamp Россия  
Дата: 28.03.05 12:21
Оценка:
Нет, не гарантируется, соответственно, не имеет.
Да здравствует мыло душистое и веревка пушистая.
Re: std::string as std::vector
От: Аноним  
Дата: 28.03.05 12:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо

Гарантируется если вызовешь c_str(), а в целом в большинстве реализаций STL не прерывный блок.
*(string.end()) выражение НЕ КОРРЕКТНО ВСЕГДА!!!! НИКОГДА НЕ ПИШИ ТАКОЕ
std::string as std::vector?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 29.03.05 03:03
Оценка: -1
#Имя: FAQ.stl.stringinside
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо

А>Гарантируется если вызовешь c_str(), а в целом в большинстве реализаций STL не прерывный блок.

Неверно. c_str() возвращает строку вида const char* заканчивающуюся 0, но никто не гарантирует, что эта строка будет ссылаться на корректное внутреннее представление. Иными словами c_str() может вернуть указатель на временный кеш, в котором будет собираться строка, а внутри она может храниться как угодно и если вы преобразуете значение, возвращаемое c_str() в char* и попытаетесь его изменить — это ни к чему не приведёт в лучшем случае, в худшем всё может упасть...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: std::string as std::vector?
От: Demay  
Дата: 29.03.05 04:37
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Аноним, Вы писали:


А>>>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо

А>>Гарантируется если вызовешь c_str(), а в целом в большинстве реализаций STL не прерывный блок.

MN>Неверно. c_str() возвращает строку вида const char* заканчивающуюся 0, но никто не гарантирует, что эта строка будет ссылаться на корректное внутреннее представление. Иными словами c_str() может вернуть указатель на временный кеш, в котором будет собираться строка, а внутри она может храниться как угодно и если вы преобразуете значение, возвращаемое c_str() в char* и попытаетесь его изменить — это ни к чему не приведёт в лучшем случае, в худшем всё может упасть...


Меня всегда интересовал такой вопрос: если предположить что c_str() возвращает указатель на временный кеш, кто его должен освобождать и как. По логике освободить кэш должна вызывающая сторона, но как ?
Мне здесь видится некое лукавство стандарта, с одной стороны не гарантируется непрерывное размещение элементов строки, а с другой стороны c_str() должна возвращать указатель на непрерывный блок оканчивающийся 0.
Уважаемый ALL подскажите реализации STL использующие для строк различные несмежные блоки памяти, хотелось бы посмотреть устройство и логику работы string.
Re[2]: std::string as std::vector?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 29.03.05 04:50
Оценка:
Здравствуйте, Demay, Вы писали:

А>>>>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо

А>>>Гарантируется если вызовешь c_str(), а в целом в большинстве реализаций STL не прерывный блок.

MN>>Неверно. c_str() возвращает строку вида const char* заканчивающуюся 0, но никто не гарантирует, что эта строка будет ссылаться на корректное внутреннее представление. Иными словами c_str() может вернуть указатель на временный кеш, в котором будет собираться строка, а внутри она может храниться как угодно и если вы преобразуете значение, возвращаемое c_str() в char* и попытаетесь его изменить — это ни к чему не приведёт в лучшем случае, в худшем всё может упасть...


D>Меня всегда интересовал такой вопрос: если предположить что c_str() возвращает указатель на временный кеш, кто его должен освобождать и как. По логике освободить кэш должна вызывающая сторона, но как ?


Кто мешает держать этот кэш внутри себя, обновлять при вызове c_str() и удалять при разрушении... Заметьте, никто не гарантирует даже следующего:
const char *str = someStlStr.c_str();
SomeFunc(str); // не факт, что здесь была передана верная строка...


И уж тем более никто не гарантирует, что будет работать это:
const char *str = someStlStr.c_str();
someStlStr += "qwert";
SomeFunc(str); // вот я не берусь сказать, что вы передали...



D>Уважаемый ALL подскажите реализации STL использующие для строк различные несмежные блоки памяти, хотелось бы посмотреть устройство и логику работы string.


Да пожалуйста: реализации stl идущие с MS VC 6.0 — 7.1 включительно... Они оптимизируют хранение строк малых размеров и внутри себя содержат 2 буфера — один выделенный статически размером в 15 символов, другой выделяется динамически, если строка вылезает за пределы 15 символов...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[3]: std::string as std::vector?
От: Demay  
Дата: 29.03.05 05:51
Оценка:
Здравствуйте, Mr. None, Вы писали:

[...]

MN>Кто мешает держать этот кэш внутри себя, обновлять при вызове c_str() и удалять при разрушении... Заметьте, никто не гарантирует даже следующего:

MN>
MN>const char *str = someStlStr.c_str();
MN>SomeFunc(str); // не факт, что здесь была передана верная строка...
MN>

Для подтверждения выше приведенного примера нельзя ли дать ссылку на стандарт ?
А также правильно ли понял фразу: "не факт, что здесь была передана верная строка..."
Из этой фразы я понял, что можной найти такие условия, при которых result будет отличен от нуля, прошу указать мне такие условия:
char plain_str[] = "12345";
std::string someStlStr(plain_str);
const char *str = someStlStr.c_str();
SomeFunc(str); // не факт, что здесь была передана верная строка...
int result = strcmp(str, plain_str);


MN>И уж тем более никто не гарантирует, что будет работать это:

MN>
MN>const char *str = someStlStr.c_str();
MN>someStlStr += "qwert";
MN>SomeFunc(str); // вот я не берусь сказать, что вы передали...
MN>


D>>Уважаемый ALL подскажите реализации STL использующие для строк различные несмежные блоки памяти, хотелось бы посмотреть устройство и логику работы string.


MN>Да пожалуйста: реализации stl идущие с MS VC 6.0 — 7.1 включительно... Они оптимизируют хранение строк малых размеров и внутри себя содержат 2 буфера — один выделенный статически размером в 15 символов, другой выделяется динамически, если строка вылезает за пределы 15 символов...


В stl идущие с MS VC 6.0 — 7.1 имеется буфер статический, а если его недостаточно, то динамический, то в конкретный момент времени используется только один, а не оба сразу,
вы не поняли вопроса: Покажите мне реализацию stl которая использует для хранения несколько несмежных буферов, а затем сливает это все в один, а затем следуя вашей точке зрения освобождает его, надо полагать делать это она должна в деструкторе string.
Re[3]: std::string as std::vector?
От: MaximE Великобритания  
Дата: 29.03.05 07:22
Оценка: 1 (1) +1
Mr. None wrote:

[]

>> Освободить кэш должна вызывающая сторона, но как ?

>
> Кто мешает держать этот кэш внутри себя, обновлять при вызове c_str() и удалять при разрушении... Заметьте, никто не гарантирует даже следующего:
>
> const char *str = someStlStr.c_str();
> SomeFunc(str); // не факт, что здесь была передана верная строка...
>


Факт. Стандарт гарантирует, что строка, полученная c_str(), остается валидной до первого вызова неконстантной ф-ции-члена строки.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: std::string as std::vector?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 29.03.05 08:35
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Mr. None wrote:


>> Кто мешает держать этот кэш внутри себя, обновлять при вызове c_str() и удалять при разрушении... Заметьте, никто не гарантирует даже следующего:

>>
>> const char *str = someStlStr.c_str();
>> SomeFunc(str); // не факт, что здесь была передана верная строка...
>>


ME>Факт. Стандарт гарантирует, что строка, полученная c_str(), остается валидной до первого вызова неконстантной ф-ции-члена строки.


Сорри — погорячился
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[4]: std::string as std::vector?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 29.03.05 08:44
Оценка:
Здравствуйте, Demay, Вы писали:

D>Здравствуйте, Mr. None, Вы писали:


D>Для подтверждения выше приведенного примера нельзя ли дать ссылку на стандарт ?


Сорри ошибся... в первом случае всё будет нормально, до тех пор пока не вызовете неконстантную функцию член...


MN>>Да пожалуйста: реализации stl идущие с MS VC 6.0 — 7.1 включительно... Они оптимизируют хранение строк малых размеров и внутри себя содержат 2 буфера — один выделенный статически размером в 15 символов, другой выделяется динамически, если строка вылезает за пределы 15 символов...


D>В stl идущие с MS VC 6.0 — 7.1 имеется буфер статический, а если его недостаточно, то динамический, то в конкретный момент времени используется только один, а не оба сразу,

D>вы не поняли вопроса: Покажите мне реализацию stl которая использует для хранения несколько несмежных буферов, а затем сливает это все в один, а затем следуя вашей точке зрения освобождает его, надо полагать делать это она должна в деструкторе string.

Ну хотите я сам напишу? Я такой не видел, но это не означает, что такой не может быть. Такое поведение не противоречит стандарту, а следовательно возможно. Например, похожим образом может себя вести строка оптимизирующая операции конкатенации... Или строка поддерживающая многопоточный доступ — в этом случае возвращаемый из c_str буфер вообще может быть для каждого потока свой... топорно и не оптимально? — возможно... но вполне законно!
Вместо того, чтобы гадать вы скажите что вам действительно нужно. Ответ на вопрос "Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти" дан — нет не гарантировано. А значение возвращаемое из c_str() вообще может быть копией и не ссылаться на внутреннее представление строки, так что, например, модифицировать его нельзя ни в коем случае.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re: std::string as std::vector
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.03.05 12:25
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо


Как уже было сказано предыдущими ораторами, способ представления строки зависит от реализации, не обязательно это должна быть последовательность. Но вот метод:

const charT * data() const;

Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first size() elements equal the corresponding elements of the string controlled by *this. If size() is zero, the member returns a non-null pointer that is copyable and can have zero added to it.

Requires: The program shall not alter any of the values stored in the character array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of basic_string that designates the same object as this.

вполне можно использовать для получения образа всей строки в виде непрерывной последовательности символов.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: std::string as std::vector
От: MaximE Великобритания  
Дата: 29.03.05 13:34
Оценка:
eao197 wrote:

> Здравствуйте, <Аноним>, Вы писали:

>
> А>Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти, как это сделано для вектора? И имеет ли строка нуль терминатор равный *(string.end()). Спасибо
>
> Как уже было сказано предыдущими ораторами, способ представления строки зависит от реализации, не обязательно это должна быть последовательность. Но вот метод:
>

> const charT * data() const;
>
> Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first size() elements equal the corresponding elements of the string controlled by *this. If size() is zero, the member returns a non-null pointer that is copyable and can have zero added to it.
>
> Requires: The program shall not alter any of the values stored in the character array. Nor shall the program treat the returned value as a valid pointer value after any subsequent call to a non-const member function of basic_string that designates the same object as this.

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

Разница между data() и c_str() в том, что последний возвращает строку гарантированно заканчивающуюся нулем, в то время как для data() таких гарантий нет. Хотя реализации, которые мне известны (Dinkum, GNU, STLPort) всегда хранят строку, завершенную нулем, и для них data() и c_str() различий в реализации не имеют.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: std::string as std::vector
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.03.05 14:10
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Разница между data() и c_str() в том, что последний возвращает строку гарантированно заканчивающуюся нулем, в то время как для data() таких гарантий нет. Хотя реализации, которые мне известны (Dinkum, GNU, STLPort) всегда хранят строку, завершенную нулем, и для них data() и c_str() различий в реализации не имеют.


Как раз с завершающим нулем могут происходить неприятные сюрпризы. Если basic_string используется для сохранения двоичных данных (я, например, так часто делаю), то работа с ней как с C-строкой смысла не имеет: если в самой стороке есть 0-символ в середине, то конструкция:
strcpy( dest, src.c_str() );

не приведет к желаемому результату, т.к. будет скопирована только часть строки до первого 0-символа в середине. И в таких случаях я предпочитаю использовать data() вместо c_str() чтобы не расчитывать на наличие или отсутствие 0-символов.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: std::string as std::vector
От: MaximE Великобритания  
Дата: 29.03.05 14:25
Оценка: +2
eao197 wrote:

> Здравствуйте, MaximE, Вы писали:

>
> ME>Разница между data() и c_str() в том, что последний возвращает строку гарантированно заканчивающуюся нулем, в то время как для data() таких гарантий нет. Хотя реализации, которые мне известны (Dinkum, GNU, STLPort) всегда хранят строку, завершенную нулем, и для них data() и c_str() различий в реализации не имеют.
>
> Как раз с завершающим нулем могут происходить неприятные сюрпризы. Если basic_string используется для сохранения двоичных данных (я, например, так часто делаю), то работа с ней как с C-строкой смысла не имеет.

А имеет ли смысл использовать string для двоичных данных? Я в таких случаях беру vector<char> — гарантированный memory layout + когда читаешь сразу ясно, что это не текст.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[5]: std::string as std::vector
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.03.05 14:57
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>eao197 wrote:


>> Здравствуйте, MaximE, Вы писали:

>>
>> ME>Разница между data() и c_str() в том, что последний возвращает строку гарантированно заканчивающуюся нулем, в то время как для data() таких гарантий нет. Хотя реализации, которые мне известны (Dinkum, GNU, STLPort) всегда хранят строку, завершенную нулем, и для них data() и c_str() различий в реализации не имеют.
>>
>> Как раз с завершающим нулем могут происходить неприятные сюрпризы. Если basic_string используется для сохранения двоичных данных (я, например, так часто делаю), то работа с ней как с C-строкой смысла не имеет.

ME>А имеет ли смысл использовать string для двоичных данных? Я в таких случаях беру vector<char> — гарантированный memory layout + когда читаешь сразу ясно, что это не текст.


Думаю, что иногда string удобнее -- поддерживаются операции контатенации, например.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: std::string as std::vector
От: MaximE Великобритания  
Дата: 29.03.05 15:00
Оценка:
eao197 wrote:

>>> Как раз с завершающим нулем могут происходить неприятные сюрпризы. Если basic_string используется для сохранения двоичных данных (я, например, так часто делаю), то работа с ней как с C-строкой смысла не имеет.

>
> ME>А имеет ли смысл использовать string для двоичных данных? Я в таких случаях беру vector<char> — гарантированный memory layout + когда читаешь сразу ясно, что это не текст.
>
> Думаю, что иногда string удобнее -- поддерживаются операции контатенации, например.

void append(vector<char>& v, char const* begin, char const* end)
{
     v.insert(v.end(), begin, end);
}


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[7]: std::string as std::vector
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 29.03.05 15:27
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>eao197 wrote:


>>>> Как раз с завершающим нулем могут происходить неприятные сюрпризы. Если basic_string используется для сохранения двоичных данных (я, например, так часто делаю), то работа с ней как с C-строкой смысла не имеет.

>>
>> ME>А имеет ли смысл использовать string для двоичных данных? Я в таких случаях беру vector<char> — гарантированный memory layout + когда читаешь сразу ясно, что это не текст.
>>
>> Думаю, что иногда string удобнее -- поддерживаются операции контатенации, например.

ME>
ME>void append(vector<char>& v, char const* begin, char const* end)
ME>{
ME>     v.insert(v.end(), begin, end);
ME>}
ME>


Это и так понятно. Но str1.append( str2 ) гораздо проще
... << RSDN@Home 1.1.4 beta 4 rev. 303>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: std::string as std::vector
От: cMex Россия ICQ: 99722815
Дата: 03.05.05 19:45
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>*(string.end()) выражение НЕ КОРРЕКТНО ВСЕГДА!!!! НИКОГДА НЕ ПИШИ ТАКОЕ


В силу чего, если не секрет?
... << RSDN@Home 1.1.3 stable >>
Re[3]: std::string as std::vector
От: LuciferMoscow Россия  
Дата: 04.05.05 06:31
Оценка:
Здравствуйте, cMex, Вы писали:
M>Здравствуйте, <Аноним>, Вы писали:
А>>*(string.end()) выражение НЕ КОРРЕКТНО ВСЕГДА!!!! НИКОГДА НЕ ПИШИ ТАКОЕ
M>В силу чего, если не секрет?
В силу того, что end итератор "указывающий" на элемент ЗА последним элементом строки(не путать с нулевым символом завершающим Си-строки!)
Re[5]: std::string as std::vector?
От: Аноним  
Дата: 04.05.05 10:01
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Ну хотите я сам напишу? Я такой не видел, но это не означает, что такой не может быть. Такое поведение не противоречит стандарту, а следовательно возможно. Например, похожим образом может себя вести строка оптимизирующая операции конкатенации... Или строка поддерживающая многопоточный доступ — в этом случае возвращаемый из c_str буфер вообще может быть для каждого потока свой... топорно и не оптимально? — возможно... но вполне законно!

MN>Вместо того, чтобы гадать вы скажите что вам действительно нужно. Ответ на вопрос "Гарантируется ли стандартом размещение элементов строки в непрерывном блоке памяти" дан — нет не гарантировано. А значение возвращаемое из c_str() вообще может быть копией и не ссылаться на внутреннее представление строки, так что, например, модифицировать его нельзя ни в коем случае.

За язык никто не тянул — давай пиши. Ждёмс...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.