4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
1 | |
std::string в char*11.06.2012, 14:13. Показов 22322. Ответов 40
Метки нет (Все метки)
0
|
11.06.2012, 14:13 | |
Ответы с готовыми решениями:
40
ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*') Странная ошибка: [Error] no match for call to '(std::string {aka std::basic_string<char>}) (int&)' (std::basic_string<char, std::char_traits<char>, std::allocator<char> > const& |
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
11.06.2012, 18:30 | 21 |
Я тоже так думаю. Хотя возможно где то хранятся эти самые строковые литералы. Нужно попробовать проверить со строкой, вводимой пользователем.
0
|
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
|
|
11.06.2012, 18:34 | 22 |
Bers, что вкладывается в понятие мёртвая память и почему она мёртвая в том примере?
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
11.06.2012, 18:34 | 23 |
Если и правда терзают сомнения, то достаточно сделать ДВА вызова c_str и сравнить эти указатели. Если они разные, то возвращается копия (но это не так, разумеется). А если одинаковые, то на внутренний буфер.
И я не знаю, как работает codepad, но в MSVC в данной программе вообще std::sting str может быть удалён оптимизирующим компилятором, как ненужный объект. Этим можно было бы объяснить неожиданное поведение программы.
0
|
Заблокирован
|
||||||
11.06.2012, 19:16 | 24 | |||||
Добавлено через 2 минуты Ни разу не сталкивался с ситуациями, где это было бы так. Однако, в книжке по STL Джосаттис об этом предупреждает. Он говорит - стандарт не гарантирует, и полагаться на это нельзя.
0
|
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
|
|
11.06.2012, 19:18 | 25 |
Ясно. Но непонятно из-за чего такие подозрения в том коде. Вывод строки работает с константной ссылкой на строку и не может вызывать неконстантные функции. А раз так, то указатель остаётся валидным.
0
|
Заблокирован
|
||||||
11.06.2012, 19:24 | 26 | |||||
0
|
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
|
|
11.06.2012, 19:30 | 27 |
Ах, да, присваивание я пропустил. Что ж, там что угодно может быть, согласен.
0
|
Заблокирован
|
|
11.06.2012, 19:54 | 28 |
Просто в студии, когда внутренее хранилище меняется, то и старые указатели смотрят на это новое внутренее хранилище (иногда). А иногда уже не смотрят (когда реалок памяти стринга).
Как бы.. выдавая наружу си-строку, стринг нарушает инвариант своего класса. Это опасная процедура. И нужна лишь для совместимости с старым си-кодом. Лучше это избегать. Я пользую сие только для сишных конструкций, и никогда при этом стринг не изменяю. Итак проблем хватает.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
11.06.2012, 19:57 | 29 |
В вышеприведённом коде в кодепаде всё выглядит так, будто возвращалась копия.
ТУт ещё такая фишка есть, что строки до 16 символов хранятся в объекте std::string в массиве фиксированного размера (в стеке) и только для бОльших строк выделяется память из кучи. С этим могло быть предыдущее поведение связанно.
0
|
59 / 6 / 1
Регистрация: 09.09.2011
Сообщений: 12
|
||||||
16.06.2012, 13:26 | 30 | |||||
12345 12345 qwert qwert qwert так что, скорее всего c_str возвращает ссылку на оригинал.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
||||||
16.06.2012, 13:41 | 31 | |||||
Она не может возвращать ссылку на оригинал, сама строка может хранится в контейнере std::string блоками в разных участках памяти, что и писали выше. std::string::c_str() лишь генерирует Си строку, указателем на которую можно безопасно пользоваться до любого изменения строки. Вот тот при мер кода, который я так же приводил в пример на 2 странице:
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
||||||
16.06.2012, 15:00 [ТС] | 32 | |||||
И что?
си строка есть строка символов, хранимых подряд в одном месте и с терминальным нолём. Возвращается не список, не дерево, не массив и не иной контейнер си строк а сама строка. Значит после std::string::c_str() такая строка существует. Почему бы теперь ни назначить внутренний указатель на строку уже на неё? Раз уж память выделена. То есть сначала меняем размещение оригинал и ставим терминальный ноль, а потом уже возвращаем указатель. При этом длина строки продолжает храниться в готовом виде. С другой стороны, можно вернуть копию и при этом указатель на неё запомнить внутри, а при повторном std::string::c_str() верунть второй раз ту же копию. Я свой кривостринг сделала сначала с возвратом оригинала, причём, данные всегда хранились в виде комбинации динамической си строки (с терминальным нолём), её длины в отдельном поле.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
16.06.2012, 15:07 | 33 |
Вы покажите цитату где я утверждал, что он всегда будет хранится в разных местах памяти? Ваш пост если честно ни о чем. Ваша реализация кого то там класса, это Ваша реализация, и я почти уверен, что она отличается от всех тех, что используют существующие компиляторы. Я могу привести другую цитату:
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
16.06.2012, 15:24 [ТС] | 34 |
Читай:
Если не может вернуть из-за размещения, значит оно всегда такое. Иначе можно привести к подходящему размещению и потом вернуть указатель на внутренние данные.
Добавлено через 2 минуты Я сам в этом уверен. Но тем не менее, отдельные аспекты класса могли придти в голову не только мне. На свой класс я ссылаюсь только как пример принципиальной возможности возвращать указатель хоть на оригинал, хоть на копию. И при возврате указателя на оригинал разработчики класса могут специально позаботиться обо всех особенностях размещения, чтоб они этот фокус позволяли. Мораль проста: если указатель на оригинал смог вернуть даже я всего через 3 месяца от начала изучения языка, то уж тем более это мог сделать, например, Страуструп, если бы счёл это целесообразным.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
16.06.2012, 15:26 | 35 |
Что не понятного из этой фразы? Или Вы считаете, что должна быть проверка, находится ли строка в одном месте или кусками, и на основании этого возвращать указатель? И опять же:
Функция генерирует си-строку...
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
16.06.2012, 15:44 [ТС] | 36 |
"Может хранить" не значит, что именно так она и хранит, фраза лишь утверждает, что нет гарантии обратного. Но обратное всё же возможно. И если оно для его то нудно разработчикам класса, то именно так и будет сделано. Можно даже сделать так, что по дефолту строка разрорвана на фрагменты, а sts::string::c_str() сначала собирает их в один во внутреннем представлении (ему же всё равно сначала надо собрать их в один), а только потом возвращает указатель и после него до следующего изменения строка уже хранится единым блоком до следующего своего изменения. Как вариант - можно хранить список нультерминальных массивов символов с индивидуальными полями длины и ещё общим полем длины, а по sts::string::c_str() приводить его к одному нультерминальному массиву символов через двойной указатель с дублированным полем полной длины.
Добавлено через 3 минуты Гипотез можно строить много, без строгих формулировок в стандарте (а "может" - не строгая, так как ничего не гарантирует) только листинг и спецификация реализации могут пролить свет на то, как в действительности хранятся данные и что возвращается. Добавлено через 2 минуты Эйси. Но "генерирует копию данных в виде си строки" и "генерирует си строку и заменяет ею текущее внутреннее представление" - далеко не одно и тоже, но то и то будет "генерирует си строку".
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
16.06.2012, 15:52 | 37 |
Да о чем Вы вообще? Куда Вас понесло?
Я и написал, что МОЖЕТ хранить, и не писал обратного, не нужно пожалуйста осознанно коверкать смысл фразы. Вы сами эту фразу поняли? Все выше Вами описанное c_str() не обязана делать, в ее задачу лишь входит генерация Си-строки, и возвращение указателя на нее, ни слова о том, что она должна как то объединять внутреннее представление строки, или вообще делать что то еще с объектом. Так зачем же разработчикам усложнять себе жизнь? Вы хоть читали полностью эту цитату? Покажу 3 раз: Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters. Добавлено через 3 минуты PS: синоним слова генерировать - создавать. Функция создает массив символов, ограниченный ноль-символом, и по содержанию идентичный строке-объекту.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
16.06.2012, 15:59 [ТС] | 38 |
Ну она же всё равно должна объединить данные объекта.
Добавлено через 1 минуту Думаешь, я этого не понимаю? Добавлено через 51 секунду Модераторы, прикройте эту тему с хвостом ни о чём, а то она давно в офтоп свалилась.
0
|
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
|
|
16.06.2012, 16:00 | 39 |
Она не должна ничего объединять. Она должна создать массив символов ( Си-строку ), идентичный по содержанию string-объекту.
0
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
|
16.06.2012, 17:05 | 40 |
Что, в стандарт сложно заглянуть? Добавлено через 26 минут Хотя все понятно. В стандарте С++98 ничего такого не описано.
2
|
16.06.2012, 17:05 | |
16.06.2012, 17:05 | |
Помогаю со студенческими работами здесь
40
Где и почему используют ту или иную строку std::string, char[], System::String^ ? char* vs std::string std::string и/или char* Преобразование std::string в char* Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |