Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
meJevin
156 / 148 / 58
Регистрация: 18.11.2015
Сообщений: 672
Завершенные тесты: 1
#1

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

08.07.2016, 00:16. Просмотров 964. Ответов 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 на самом деле? Можете объяснить простым языком, если не трудно?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2016, 00:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Немного про std::string (C++):

std::string, std::fstream, ошибка кучи - C++
где то начало вылетать при операции += с локальной переменной std::string. Заменил на свой qString. Замечательно, то же самое... ошибка при...

Файловый поток и std::string - C++
добрый день сейчас меня немножко ввело в тупняк - из файлового потока(ifstream) нельзя прочитать по словам типа std::string? только char*...

как проинициализировать std::stack<const int> obj ( std::stack<int>{} ); - C++
добрый день. вопрос в коде: http://rextester.com/VCVVML6656 #include &lt;iostream&gt; #include &lt;stack&gt; //-std=c++14...

std::filesystem && std::asio и пр - C++
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же ожидается lexical_cast, any, string_algo и т.д.) и вообщем везде...

Немного философии ООП - C++
На днях на работе возник холивар с коллегами, к правильному решению пришли только на следующий день, почитав Мейерса и Саттера (один из...

Разделить vector<string> на два vector<string> - C++
У меня есть vector&lt;string&gt; line_from_file; line_from_file.resize(N); N-некое число Когда я встречу точку &quot;.&quot; в...

34
HenryDukart
123 / 123 / 35
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 15:14 #16
avgoor, про внутреннюю реализацию ни слова.

Добавлено через 19 минут
avgoor, ну ни слова это я загул конечно. Спасибо за такое точное определение.

Специально наперекор использование структуры массива могу предложить использование структуры список, где элементы размещаются последовательно в выделенном участке памяти (с помощью new с размещением). Конечно, никакой рациональностью тут и не пахнет, но все же.
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
08.07.2016, 15:41 #17
Цитата Сообщение от HenryDukart Посмотреть сообщение
Mr.X, разве где-то описывается внутреннее устройство контейнера?
Ой, пардон, я вектор имел в виду.
Для него в стандарте есть требование, чтобы он в памяти был подобен массиву.
0
HenryDukart
123 / 123 / 35
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 15:54 #18
Mr.X, вы, наверное, про метод data().
0
avgoor
915 / 550 / 119
Регистрация: 05.12.2015
Сообщений: 1,531
08.07.2016, 15:58 #19
Цитата Сообщение от HenryDukart Посмотреть сообщение
Специально наперекор использование структуры массива могу предложить использование структуры список, где элементы размещаются последовательно в выделенном участке памяти (с помощью new с размещением)
А указатели где хранить? В другом месте будет массив {1, 2, 3, 4, 5, ...}? Зачем? И самое главное, если список всегда располагается в памяти по последовательным адресам - такой список называется массивом.
В прочем выше я уже писал: "теоретически, можно...".
0
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
08.07.2016, 16:25 #20
Цитата Сообщение от HenryDukart Посмотреть сообщение
Mr.X, вы, наверное, про метод data().
Я про то, что элементы вектора по стандарту хранятся в массиве, а адрес первого элемента вектора указывает на начало этого массива.
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,047
Записей в блоге: 17
26.07.2016, 23:31 #21
Цитата Сообщение от meJevin Посмотреть сообщение
Привет, читал про std::string на разных сайтах.
Не могу сказать как в стандарте, но ведет себя он приблизительно так же как std::vector<char> (но реальный размер +1 под "\0").

Добавлено через 2 минуты
Цитата Сообщение от avgoor Посмотреть сообщение
А указатели где хранить? В другом месте будет массив {1, 2, 3, 4, 5, ...}? Зачем? И самое главное, если список всегда располагается в памяти по последовательным адресам - такой список называется массивом.
В прочем выше я уже писал: "теоретически, можно...".
При списке возникнет проблема с реализацией c_str()
0
hoggy
6701 / 2883 / 494
Регистрация: 15.11.2014
Сообщений: 6,480
Завершенные тесты: 1
26.07.2016, 23:55 #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 Посмотреть сообщение
Т.е. под капотом у него может быть только си-строка
нет, потому что не обязана быть нуль-терминированной.
1
avgoor
915 / 550 / 119
Регистрация: 05.12.2015
Сообщений: 1,531
26.07.2016, 23:58 #23
Цитата Сообщение от hoggy Посмотреть сообщение
нет, потому что не обязана быть нуль-терминированной
Обязана. Читайте требования к operator[]
Цитата Сообщение от Avazart Посмотреть сообщение
При списке возникнет проблема с реализацией c_str()
Я писал ровно то же самое.
Немного про std::string
0
_Ivana
3185 / 1801 / 153
Регистрация: 01.03.2013
Сообщений: 5,030
Записей в блоге: 3
26.07.2016, 23:58 #24
Цитата Сообщение от hoggy Посмотреть сообщение
стандарт явно требует
Цитата Сообщение от _Ivana Посмотреть сообщение
Да шел бы он, стандарт (простите за непопулярное имхо)
И вроде уже выяснили, что если говорить про std::string из С++ - тогда да, только как велит стандарт. А если про "как вообще можно" - то как угодно.
0
hoggy
6701 / 2883 / 494
Регистрация: 15.11.2014
Сообщений: 6,480
Завершенные тесты: 1
26.07.2016, 23:59 #25
Цитата Сообщение от HenryDukart Посмотреть сообщение
структуры список, где элементы размещаются последовательно
элементами списка являются ноды - объекты, которые держат указатель на след. ноду.
по стандарту там должны быть буковки.

поэтому лист не подойдет внезависимости от аллокатора.
0
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,047
Записей в блоге: 17
27.07.2016, 00:02 #26
Цитата Сообщение от _Ivana Посмотреть сообщение
А если про "как вообще можно" - то как угодно.
В С++ много чего можно... но говорить про "все" - лишено смысла.
0
hoggy
6701 / 2883 / 494
Регистрация: 15.11.2014
Сообщений: 6,480
Завершенные тесты: 1
27.07.2016, 00:04 #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().

то бишь правомерно обращаться к элементу за последней буковкой.
то бишь к нулю?
0
_Ivana
3185 / 1801 / 153
Регистрация: 01.03.2013
Сообщений: 5,030
Записей в блоге: 3
27.07.2016, 00:04 #28
Avazart, у многих и вся жизнь лишена смысла, так что обсуждать смысл - занятие неблагодарное. Я вот так широко понял (и продолжаю понимать) вопрос ТС, оппоненты тычут в нос стандартом и говорят "нельзя"...
0
avgoor
915 / 550 / 119
Регистрация: 05.12.2015
Сообщений: 1,531
27.07.2016, 00:09 #29
Цитата Сообщение от hoggy Посмотреть сообщение
то бишь правомерно обращаться к элементу за последней буковкой
Да, правомерно читать нуль-терминатор с помощью [] (который должен выдавать непрерывную память - т.е. нуль терминатор хранится всегда). Писать что-то в нуль терминатор - UB.
2
Avazart
Эксперт С++
7247 / 5419 / 297
Регистрация: 10.12.2010
Сообщений: 24,047
Записей в блоге: 17
27.07.2016, 00:11 #30
Цитата Сообщение от hoggy Посмотреть сообщение
то бишь правомерно обращаться к элементу за последней буковкой.
то бишь к нулю?
Получается что так, только возникает вопрос что, если
C++
1
str[str.size()] = 'a';
1
27.07.2016, 00:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.07.2016, 00:11
Привет! Вот еще темы с ответами:

std::defaultfloat - C++
Есть такая тема в новом стандарте как std::defaultfloat Описание: http://www.cplusplus.com/reference/ios/defaultfloat/ В стандарте...

переписать std::map - C++
Добрый вечер! Есть работающая программа, в которой используется map, все работало хорошо, но теперь немного изменились условия и объем...

Вопрос по std::map - C++
В качестве хэш-таблицы для строк (AnsiString) я использовал std::map. От таблицы мне нужно было ещё и такое свойство: я хотел иметь...

Std::function<>::target() возвращает 0 - C++
Привет! Не удовольствия для, а фриланса ради пришлось работать с WinAPI. Всем известно, что это чистый С. Так вот захотел я привязать...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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