Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
meJevin
156 / 148 / 92
Регистрация: 18.11.2015
Сообщений: 674
Завершенные тесты: 1
#1

Немного про std::string

08.07.2016, 00:16. Просмотров 1098. Ответов 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, std::fstream, ошибка кучи
где то начало вылетать при операции += с локальной переменной std::string....

Файловый поток и std::string
добрый день сейчас меня немножко ввело в тупняк - из файлового...

Как проинициализировать std::stack<const int> obj ( std::stack<int>{} );
добрый день. вопрос в коде: http://rextester.com/VCVVML6656 #include...

std::filesystem && std::asio и пр
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же...

Немного философии ООП
На днях на работе возник холивар с коллегами, к правильному решению пришли...

34
_Ivana
3233 / 1861 / 235
Регистрация: 01.03.2013
Сообщений: 5,091
Записей в блоге: 5
08.07.2016, 00:26 #2
Цитата Сообщение от meJevin Посмотреть сообщение
каким еще образом можно в памяти хранить
да любым - например, в виде односвязного списка чаров.

ЗЫ1: если абстракция предоставляет внешний апи - не стоит лезть и курочить ее нутрь. Потому что завтра новый Степанов перепишет эти стринги по-другому с сохранением апи, и ваша программа, рассчитывающая на нуль-терминатор, может свалиться. Например, паскалевские строки - хранят размер в первом байте. И можно на это рассчитывать. Но тогда длина не более 255, кому-то это однажды надоело, и он стал хранить длину в первом слове - двух байтах. И кто пользовался апи - не заметили, а кто рассчитывал на реализацию - приплыли.

ЗЫ2: расположение строк строго в линейной области памяти - это хорошо. В Си. А в Яве с Шарпом решили гениально совместить это требование (само по себе необязательное - см. п 1) с иммутабельностью строк И начались ужасы от тех, кто не особо понимал, как это готовить без всяких стрингбилдеров, ибо при для иммутабельности строки при операциях (конкатенация/выделение подстроки и т.п.) копируются в новые области памяти, которые аллоцируются, и если в цикле - то долго и медленно... И из-за этой имхо странной реализации многие не желающие думать императивные программисты делают вывод о том, что иммутабельные структуры данных в функциональных языках всегда копируются и жрут память и время....
0
meJevin
156 / 148 / 92
Регистрация: 18.11.2015
Сообщений: 674
Завершенные тесты: 1
08.07.2016, 00:45  [ТС] #3
Цитата Сообщение от _Ivana Посмотреть сообщение
да любым - например, в виде односвязного списка чаров.
Это понятно, но ведь по перформансу-то долбанет же? Поэтому лучше всего contiguously in memory, так?
0
HenryDukart
124 / 124 / 44
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 00:48 #4
meJevin, требования ко всем контейнерам предъявляются не на их реализацию, а на производительность. Реализовать можете как угодно, лишь бы удовлетворяло условиям сложности.
0
_Ivana
3233 / 1861 / 235
Регистрация: 01.03.2013
Сообщений: 5,091
Записей в блоге: 5
08.07.2016, 00:50 #5
Цитата Сообщение от meJevin Посмотреть сообщение
так?
Ну вы же не вчера структуры данных узнали. Долбанет по доступу за О(1) к любому элементу, зато позволит быстро расширять с головы, в отличие от стандартных массивов. В хаскеле, например, 2 типа строк - высокоуровневые - списки чаров, низкоуровневые - байтстринги. Тот же Джоэл Спольски, когэа в Майкрософте Эксель на Сях костылил, влепил туда паскалевские строки - "поэтому Эксель такой быстрый" (С). Короче - в зависит от области применения.
0
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 02:24 #6
Цитата Сообщение от _Ivana Посмотреть сообщение
да любым - например, в виде односвязного списка чаров.
Неправда ваша. В стандарте четко написано:
A basic_string is a contiguous container
Т.е. под капотом у него может быть только си-строка. (Почему не просто массив чаров без терминального нуля - тоже написано, но в требованиях к operator[], c_str() и data(), которая в c++17, кстати, станет неконстантной).
0
_Ivana
3233 / 1861 / 235
Регистрация: 01.03.2013
Сообщений: 5,091
Записей в блоге: 5
08.07.2016, 02:38 #7
Цитата Сообщение от avgoor Посмотреть сообщение
В стандарте четко написано
Да шел бы он, стандарт (простите за непопулярное имхо) ТС спрашивал каким еще образом можно - я ответил.
0
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 02:39 #8
Цитата Сообщение от _Ivana Посмотреть сообщение
ТС спрашивал каким еще образом можно - я ответил
Но, господин! Если:
Цитата Сообщение от _Ivana Посмотреть сообщение
Да шел бы он, стандарт
то это будет не std::string из C++.
0
_Ivana
3233 / 1861 / 235
Регистрация: 01.03.2013
Сообщений: 5,091
Записей в блоге: 5
08.07.2016, 02:42 #9
Резонно На это мы или свой буст не стд-шный навелосипедим, или стандарт поменяем (вроде какая-то российская компания стала официальным членом комитета что-ли, и может принимать предложения от соотечественников). Или и то и другое одновременно
0
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 02:48 #10
Цитата Сообщение от _Ivana Посмотреть сообщение
Или и то и другое одновременно
Даже если и так, std::string всегда будет содержать способ каста к си-строке "для совместимости"™. Теоретически можно сделать стринг на списках, с мутабельным массивом, и только кэшировать туда данные. Но, так может сделать только "мудакъ"®. А реализацию STL "мудаки"® не пишут.
1
_Ivana
3233 / 1861 / 235
Регистрация: 01.03.2013
Сообщений: 5,091
Записей в блоге: 5
08.07.2016, 03:00 #11
Цитата Сообщение от avgoor Посмотреть сообщение
всегда будет содержать способ каста к си-строке "для совместимости"™
И что? Уж каст то для совместимости можно сделать из чего угодно.
Цитата Сообщение от avgoor Посмотреть сообщение
Но, так может сделать только "мудакъ"®. А реализацию STL "мудаки"® не пишут.
Я не знаком с авторами стл, чтобы иметь о них какое-либо мнение. Зато хорошо знаком с одним парнем, который выкинул нахрен все стл-ство (на которое молились предыдущие разрабы) из пендосского проекта, написал свои реализации и убыстрил его в несколько раз.
0
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 03:06 #12
Цитата Сообщение от _Ivana Посмотреть сообщение
написал свои реализации и убыстрил его в несколько раз
Та же фигня. Но это - фундаментальное свойство любой техники: Любое специальное устройство всегда оптимальнее общего.
Цитата Сообщение от _Ivana Посмотреть сообщение
Уж каст то для совместимости можно сделать из чего угодно.
Вопрос цены (в смысле затрат памяти итд).
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
08.07.2016, 04:20 #13
Цитата Сообщение от HenryDukart Посмотреть сообщение
meJevin, требования ко всем контейнерам предъявляются не на их реализацию, а на производительность. Реализовать можете как угодно, лишь бы удовлетворяло условиям сложности.
Да ладно! Так-то по стандарту контейнер, например, есть массив, т.е. занимает непрерывный кусок памяти.
0
HenryDukart
124 / 124 / 44
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 11:25 #14
Mr.X, разве где-то описывается внутреннее устройство контейнера?
1
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 14:47 #15
Цитата Сообщение от HenryDukart Посмотреть сообщение
разве где-то описывается внутреннее устройство контейнера?
Адын:
21.3.1 Class template basic_string
3 A basic_string is a contiguous container
Два:
23.2.1 General container requirements
13 A contiguous container is a container that supports random access iterators and whose member types iterator and const_iterator are contiguous iterators
Три:
24.2 Iterator requirements
24.2.1 In general
5 Iterators that further satisfy the requirement that, for integral values n and dereferenceable iterator values a and (a + n), *(a + n) is equivalent to *(addressof(*a) + n), are called contiguous iterators.
0
HenryDukart
124 / 124 / 44
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 15:14 #16
avgoor, про внутреннюю реализацию ни слова.

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

Специально наперекор использование структуры массива могу предложить использование структуры список, где элементы размещаются последовательно в выделенном участке памяти (с помощью new с размещением). Конечно, никакой рациональностью тут и не пахнет, но все же.
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
08.07.2016, 15:41 #17
Цитата Сообщение от HenryDukart Посмотреть сообщение
Mr.X, разве где-то описывается внутреннее устройство контейнера?
Ой, пардон, я вектор имел в виду.
Для него в стандарте есть требование, чтобы он в памяти был подобен массиву.
0
HenryDukart
124 / 124 / 44
Регистрация: 05.10.2013
Сообщений: 457
Завершенные тесты: 2
08.07.2016, 15:54 #18
Mr.X, вы, наверное, про метод data().
0
avgoor
1008 / 602 / 157
Регистрация: 05.12.2015
Сообщений: 1,686
08.07.2016, 15:58 #19
Цитата Сообщение от HenryDukart Посмотреть сообщение
Специально наперекор использование структуры массива могу предложить использование структуры список, где элементы размещаются последовательно в выделенном участке памяти (с помощью new с размещением)
А указатели где хранить? В другом месте будет массив {1, 2, 3, 4, 5, ...}? Зачем? И самое главное, если список всегда располагается в памяти по последовательным адресам - такой список называется массивом.
В прочем выше я уже писал: "теоретически, можно...".
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
08.07.2016, 16:25 #20
Цитата Сообщение от HenryDukart Посмотреть сообщение
Mr.X, вы, наверное, про метод data().
Я про то, что элементы вектора по стандарту хранятся в массиве, а адрес первого элемента вектора указывает на начало этого массива.
0
08.07.2016, 16:25
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2016, 16:25

Разделить vector<string> на два vector<string>
У меня есть vector&lt;string&gt; line_from_file; line_from_file.resize(N); ...

std::defaultfloat
Есть такая тема в новом стандарте как std::defaultfloat Описание:...

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


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

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

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