Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
meJevin
154 / 146 / 57
Регистрация: 18.11.2015
Сообщений: 629
Завершенные тесты: 1
#1

Немного про std::string - C++

08.07.2016, 00:16. Просмотров 847. Ответов 34
Метки нет (Все метки)

Привет, читал про std::string на разных сайтах.


1. Там говорят, С++ 11 гарантирует, что std::string будет stored contiguously in memory. В этом я не сомневаюсь, но каким еще образом можно в памяти хранить std::string?

2. Говорят, что std::string на самом деле имеет null-terminator на конце. Это так? Вроде да, я в этом немного убедился в своей студии. Сделал четыре std::string'a, через цикл от 0 до size()+1 вывел все представления их символов в виде int, и да, последний символ был '\0' (в int виде просто 0).

Но все равно, некоторые говорят, что если мы имеем std::string str("hello"); и пытаемся получить доступ к желанному null-terminator'у, у нас может быть UB. Т.е. писать такое: std::cout << (int)str[str.size()] << std::endl; не стоит. Правда может быть UB?

3. Что под капотом у std::string на самом деле? Можете объяснить простым языком, если не трудно?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2016, 00:16     Немного про std::string
Посмотрите здесь:

std::string C++
std::string, std::fstream, ошибка кучи C++
std:string C++
std::string -> std::wstring C++
C++ std::string
C++ про std
C++ std::string + std::remove
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
7063 / 5240 / 262
Регистрация: 10.12.2010
Сообщений: 23,052
Записей в блоге: 17
26.07.2016, 23:31     Немного про std::string #21
Цитата Сообщение от meJevin Посмотреть сообщение
Привет, читал про std::string на разных сайтах.
Не могу сказать как в стандарте, но ведет себя он приблизительно так же как std::vector<char> (но реальный размер +1 под "\0").

Добавлено через 2 минуты
Цитата Сообщение от avgoor Посмотреть сообщение
А указатели где хранить? В другом месте будет массив {1, 2, 3, 4, 5, ...}? Зачем? И самое главное, если список всегда располагается в памяти по последовательным адресам - такой список называется массивом.
В прочем выше я уже писал: "теоретически, можно...".
При списке возникнет проблема с реализацией c_str()
hoggy
6157 / 2523 / 443
Регистрация: 15.11.2014
Сообщений: 5,574
Завершенные тесты: 1
26.07.2016, 23:55     Немного про std::string #22
Цитата Сообщение от meJevin Посмотреть сообщение
но каким еще образом можно в памяти хранить std::string?
никаким.
Цитата Сообщение от meJevin Посмотреть сообщение
Это так?
это не гарантируется.

Цитата Сообщение от meJevin Посмотреть сообщение
Правда может быть UB?
да

Цитата Сообщение от _Ivana Посмотреть сообщение
да любым - например, в виде односвязного списка чаров.
вы ошибаетесь.

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

21.4.1 basic_string general requirements
5 The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string
object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0
<= n < s.size().
Добавлено через 1 минуту
Цитата Сообщение от avgoor Посмотреть сообщение
Т.е. под капотом у него может быть только си-строка
нет, потому что не обязана быть нуль-терминированной.
avgoor
880 / 515 / 111
Регистрация: 05.12.2015
Сообщений: 1,457
26.07.2016, 23:58     Немного про std::string #23
Цитата Сообщение от hoggy Посмотреть сообщение
нет, потому что не обязана быть нуль-терминированной
Обязана. Читайте требования к operator[]
Цитата Сообщение от Avazart Посмотреть сообщение
При списке возникнет проблема с реализацией c_str()
Я писал ровно то же самое.
Немного про std::string
_Ivana
2838 / 1663 / 143
Регистрация: 01.03.2013
Сообщений: 4,757
Записей в блоге: 2
26.07.2016, 23:58     Немного про std::string #24
Цитата Сообщение от hoggy Посмотреть сообщение
стандарт явно требует
Цитата Сообщение от _Ivana Посмотреть сообщение
Да шел бы он, стандарт (простите за непопулярное имхо)
И вроде уже выяснили, что если говорить про std::string из С++ - тогда да, только как велит стандарт. А если про "как вообще можно" - то как угодно.
hoggy
6157 / 2523 / 443
Регистрация: 15.11.2014
Сообщений: 5,574
Завершенные тесты: 1
26.07.2016, 23:59     Немного про std::string #25
Цитата Сообщение от HenryDukart Посмотреть сообщение
структуры список, где элементы размещаются последовательно
элементами списка являются ноды - объекты, которые держат указатель на след. ноду.
по стандарту там должны быть буковки.

поэтому лист не подойдет внезависимости от аллокатора.
Avazart
7063 / 5240 / 262
Регистрация: 10.12.2010
Сообщений: 23,052
Записей в блоге: 17
27.07.2016, 00:02     Немного про std::string #26
Цитата Сообщение от _Ivana Посмотреть сообщение
А если про "как вообще можно" - то как угодно.
В С++ много чего можно... но говорить про "все" - лишено смысла.
hoggy
6157 / 2523 / 443
Регистрация: 15.11.2014
Сообщений: 5,574
Завершенные тесты: 1
27.07.2016, 00:04     Немного про std::string #27
Цитата Сообщение от _Ivana Посмотреть сообщение
И вроде уже выяснили, что если говорить про std::string из С++ - тогда да, только как велит стандарт. А если про "как вообще можно" - то как угодно.
ТС спрашивал об std::string.

"как вообще" - оффтопик, который не представляет интереса в рамках данной темы.
Цитата Сообщение от avgoor Посмотреть сообщение
Обязана. Читайте требования к operator[]

вот здесь:
21.4.5 basic_string element access [string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 Requires: pos <= size().
2 Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type
charT with value charT(), where modifying the object leads to undefined behavior.
3 Throws: Nothing.
4 Complexity: constant time.
я так понял собака зарыта:
1 Requires: pos <= size().

то бишь правомерно обращаться к элементу за последней буковкой.
то бишь к нулю?
_Ivana
2838 / 1663 / 143
Регистрация: 01.03.2013
Сообщений: 4,757
Записей в блоге: 2
27.07.2016, 00:04     Немного про std::string #28
Avazart, у многих и вся жизнь лишена смысла, так что обсуждать смысл - занятие неблагодарное. Я вот так широко понял (и продолжаю понимать) вопрос ТС, оппоненты тычут в нос стандартом и говорят "нельзя"...
avgoor
880 / 515 / 111
Регистрация: 05.12.2015
Сообщений: 1,457
27.07.2016, 00:09     Немного про std::string #29
Цитата Сообщение от hoggy Посмотреть сообщение
то бишь правомерно обращаться к элементу за последней буковкой
Да, правомерно читать нуль-терминатор с помощью [] (который должен выдавать непрерывную память - т.е. нуль терминатор хранится всегда). Писать что-то в нуль терминатор - UB.
Avazart
7063 / 5240 / 262
Регистрация: 10.12.2010
Сообщений: 23,052
Записей в блоге: 17
27.07.2016, 00:11     Немного про std::string #30
Цитата Сообщение от hoggy Посмотреть сообщение
то бишь правомерно обращаться к элементу за последней буковкой.
то бишь к нулю?
Получается что так, только возникает вопрос что, если
C++
1
str[str.size()] = 'a';
avgoor
880 / 515 / 111
Регистрация: 05.12.2015
Сообщений: 1,457
27.07.2016, 00:12     Немного про std::string #31
Цитата Сообщение от Avazart Посмотреть сообщение
Получается что так, только возникает вопрос что, если
UB.
Avazart
7063 / 5240 / 262
Регистрация: 10.12.2010
Сообщений: 23,052
Записей в блоге: 17
27.07.2016, 00:14     Немного про std::string #32
Цитата Сообщение от avgoor Посмотреть сообщение
UB.
Можно предположить что до первого .c_str() или .data() все может быть нормально...
или нет перефразирую что все будет нормально до передачи в ф-цию вычисляющую длину по \0.

Ибо сам std::string как я понимаю опирается не на \0 а на внутреннюю переменную m_size.
Ибо такие вещи как
C++
1
std::string str= "line1\0line2\0line3";
имеют места быть.
avgoor
880 / 515 / 111
Регистрация: 05.12.2015
Сообщений: 1,457
27.07.2016, 00:16     Немного про std::string #33
Цитата Сообщение от Avazart Посмотреть сообщение
Можно предположить что до первого .c_str() или .data() все может быть нормально... или нет что все будет нормально до передачи в ф-цию вычисляющую длину по \0
На то оно и UB, что предполагать как оно будет - неблагодарное дело.
Avazart
7063 / 5240 / 262
Регистрация: 10.12.2010
Сообщений: 23,052
Записей в блоге: 17
27.07.2016, 00:42     Немного про std::string #34
Кстати спонтанно возник такой код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// Example program
#include <iostream>
#include <string>
 
struct UserType
{
};
 
int main()
{
  std::basic_string<UserType> x;
  x[x.size()];  // ??
}
Что является нулем в конце, если тип пользовательский?

По идее за это должен отвечать std::char_traits<>
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.07.2016, 01:32     Немного про std::string
Еще ссылки по теме:

C++ Builder Перевод строк std::string, std::wstring в Unicode (String)
Std::string compare C++
Заменить std::string на (String, UnicodeString, wchar_t) C++ Builder
Std::string C++
C++ 'string' : undeclared identifier, std::string

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
hoggy
6157 / 2523 / 443
Регистрация: 15.11.2014
Сообщений: 5,574
Завершенные тесты: 1
27.07.2016, 01:32     Немного про std::string #35
Цитата Сообщение от Avazart Посмотреть сообщение
Что является нулем в конце, если тип пользовательский?
C++
1
2
const auto null_terminator 
    = typename std::basic_string<T>::value_type();
Yandex
Объявления
27.07.2016, 01:32     Немного про std::string
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru