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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 94, средняя оценка - 4.91
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

std::string в char* - C++

11.06.2012, 14:13. Просмотров 13368. Ответов 40
Метки нет (Все метки)

Можно ли привести std::string к указателю на нуль-терминальную строку? Как?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.06.2012, 14:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос std::string в char* (C++):

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri - C++
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*') - C++
int main() { string fileName, currWord, currMax = &quot;&quot;; cin&gt;&gt;fileName; freopen(fileName, &quot;r&quot;, stdin); while...

(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const& - C++
astxx::manager::connection::connection(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned short); ...

Где и почему используют ту или иную строку std::string, char[], System::String^ ? - C++
Где и почему используют ту или иную строку std::string, char, System::String^ ? Объясните пожалуйста где нужно использовать...

char* vs std::string - C++
При чтении чужих сорцов, обратил внимание, что в роли аргументов для функций/методов, как правило используются указатели на массивы чаров,...

Std::string в const char* - C++
можно ли std::string превратить в const char* и как это сделать?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.06.2012, 14:17 #2
string::c_str()
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.06.2012, 14:50  [ТС] #3
Думаешь, я не могу этого сам написать? Я имел ввиду готовый член. Он существует?
Bers
Заблокирован
11.06.2012, 14:56 #4
Цитата Сообщение от taras atavin Посмотреть сообщение
Можно ли привести std::string к указателю на нуль-терминальную строку? Как?
Нельзя.

Но можно сделать эквивалентную по смыслу операцию:

C++
1
2
3
4
5
6
7
8
9
int main()
{
    std::string test("trololo");
 
    char* ptr = &test[0]; //получаем указатель на первый символ си-строчки
 
    std::cout<<ptr<<std::endl;
    return 0;
}
Но крайне не рекомендуется. Ибо нет никакой гарантии, что внутреннее хранилище стринга является непрерывным блоком памяти.
(разные реализации стандартной библиотеки могут по разному реализовывать std::string)

Безопасным способом является получение си-строки через метод: string::c_str()
Однако, данный метод обязан вернуть указатель на си-строку эквивалентную тому значению, что хранит в себе сам стринг. Это означает, что если стринг хранит данные не в непрерывном блоке памяти, то ему придётся выполнить ряд действий по созданию такого непрерывного блока памяти, чтобы предоставить указатель на него наружу, что приведет к падению производительности.

Если нужно гарантировать возможность быстрой работы, то можно использовать std::vector<char>, который исходя из ряда требований к контейнеру всегда хранит данные в непрерывном блоке памяти. И тогда запись:

C++
1
char* ptr = &test[0];
гарантированно будет валидна.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.06.2012, 15:00  [ТС] #5
Цитата Сообщение от Bers Посмотреть сообщение
Безопасным способом является получение си-строки через метод: string::c_str()
Однако, данный метод обязан вернуть указатель на си-строку эквивалентную тому значению, что хранит в себе сам стринг. Это означает, что если стринг хранит данные не в непрерывном блоке памяти, то ему придётся выполнить ряд действий по созданию такого непрерывного блока памяти, что предоставить указатель на него наружу, что приведет к падению производительности.
Это разовая операция с достаточно короткой строкой, менее сотни символов, а времени на неё не жалко двух секунд. Требуется ли освобождать указатель, который вернёт string::c_str()?
Bers
Заблокирован
11.06.2012, 15:01 #6
Цитата Сообщение от taras atavin Посмотреть сообщение
Думаешь, я не могу этого сам написать? Я имел ввиду готовый член. Он существует?
Можно унаследоваться от std::string и определить свой собственный operator char*()
И тогда приведение будет доступно без явного вызова c_str()

Добавлено через 41 секунду
Цитата Сообщение от taras atavin Посмотреть сообщение
Это разовая операция с достаточно короткой строкой, менее сотни символов, а времени на неё не жалко двух секунд. Требуется ли освобождать указатель, который вернёт string::c_str()?
Ни в коем случае. Данные являются собственностью стринга, а не вызывающей стороны.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.06.2012, 15:07 #7
Да вот как раз таки нужно освобождать. c_str() генерирует строку, и возвращает указатель на нее. Если к примеру изменить сам объект std::string после генерирования этой строки, то последняя в свою очередь не изменится. Нужно удалять эту строку как любой другой массив
C++
1
delete [] ptr;
Добавлено через 1 минуту
Хотя нет, я поспешил, и скорей всего не прав.
Bers
Заблокирован
11.06.2012, 15:09 #8
Цитата Сообщение от Toshkarik Посмотреть сообщение
Да вот как раз таки нужно освобождать. c_str() генерирует строку, и возвращает указатель на нее.
Хм... кстати.. а это вопрос:


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.

A terminating null character is automatically appended.

The returned array points to an internal location with the required storage space for this sequence of characters plus its terminating null-character, but the values in this array should not be modified in the program and are only guaranteed to remain unchanged until the next call to a non-constant member function of the string object.

Нужно проверить, будет ли утечка.
Но вот сам лично я никогда не освобождал память, которую сам не создавал. И вроде бы утечек не было.


C++
1
2
3
4
5
6
7
8
9
10
int main()
{
    
    std::string test("trololo");
    const char* ptr = test.c_str();
 
   // delete [] ptr;  //если расскоментировать, получаем порчу памяти
 
    return 0;
}
итого: удалять стринговые данные нельзя
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
11.06.2012, 15:13 #9
Строку, которую возвращает std::string::c_str() освобождать не только не надо, но и нельзя.
Ну и &test[0] для std::string не годится не только из-за возможной не непрерывности, но и потому, что строка не обязательно будет заканчиваться нулём. Скажем std::string::data() возвращает непрерываный блок, но нуля в конце там тоже не обещается, в отличие от c_str().
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.06.2012, 15:14  [ТС] #10
Цитата Сообщение от Bers Посмотреть сообщение
Ни в коем случае. Данные являются собственностью стринга, а не вызывающей стороны.
Ну я когда свой кривостринг делал, sting::operator char* возвращал копию. Соответственно нужен был delete.
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
11.06.2012, 15:15 #11
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну я когда свой кривостринг делал, sting::operator char* возвращал копию.
Стандартный тоже может возвращать копию. Только копией этой владеет сам объект строки.
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.06.2012, 15:17 #12
Да, сгенерированная строка не меняется при изменении самого объекта. Нужно вызывать повторно функцию, чтоб изменилась и Си строка. Мысль про освобождение памяти - скорей всего выделенная память под строку освобождается при удалении объекта.
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
11.06.2012, 15:20 #13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Да, сгенерированная строка не меняется при изменении самого объекта.
Этого, кстати, тоже никто не обещает. Результат c_str() можно считать валидным лишь до тех пор, пока для строки вызываются только константные функции.
Bers
Заблокирован
11.06.2012, 15:22 #14
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну я когда свой кривостринг делал, sting::operator char* возвращал копию. Соответственно нужен был delete.
Есть правило: кто память выделял, тот её и освобождает.
К тому же, тот кто выделял - тот знает точно: как он выделял. А значит лучше знает, как правильно освободить. Чего не скажешь о вызывающей стороне.

Единственное исключение из этого правила - это специализированные инструменты, которые управляют временем жизни объекта (всякие там смартпоинтеры).

Если придерживаться этого правила, то путаницы не возникает.
На примере std::string видно, что она этого правила придерживается.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.06.2012, 15:24  [ТС] #15
Это константа.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.06.2012, 15:24
Привет! Вот еще темы с ответами:

std::string и/или char* - C++
Здравствуйте. пишу метод построчной обработки данных из файла Вот он: bool loadFromFile(std::string fileName) { ...

Перевод массива char в std::string в определенном формате - C++
Имеится char a=&quot;145&quot;; нужно его превратить в std::string , но чтоб string b=&quot;&quot;; тоесть чтоб скобки добавились. ...

Найти вхождение одного символа std::string в строку char* - C++
Каким образом можно найти вхождение одного символа std::string в строку char*? Наоборот то понятное дело как, но нужно именно так

Преобразовать const unsigned char* в std::string (или _bstr_t ) - C++
Здравствуйте старшие товарищи! Есть функция, которая возвращает результат типа const unsigned char*. а мне нужно получить ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.06.2012, 15:24
Ответ Создать тему
Опции темы

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