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

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

Войти
Регистрация
Восстановить пароль
 
 
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
#1

Сколько живёт строковый литерал? - C++

06.02.2014, 18:00. Просмотров 1091. Ответов 26
Метки нет (Все метки)

Имеется код
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
using namespace std;
 
class myClass
{
public:
    myClass(char *s){str=s;}
    void print() {cout << str << endl;}
 
private:
    char *str;
};
 
int main()
{
    myClass a("ne erunda li?");
 
    a.print();
 
    cout << "Hello World!" << endl;
    return 0;
}
Сколько живёт строковый литерал? Не будет ли такой проблемы, что после выходе из конструктора в память, где ранее хранилось "ne erunda li?\0", будет записано что-то ещё?

Кстати, компилятор выдаёт предупреждение с указанием на строчку, где объявляется объект:
C:\Users\Students\Documents\untitled8\main.cpp:17: предупреждение: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
myClass a("ne erunda li?");
^
Как можно это обойти с минимальными изменениями кода класса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2014, 18:00
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сколько живёт строковый литерал? (C++):

Строковый литерал - C++
Вопрос к профи: Верно ли что, когда мы инициализирум строку вот так: const char *str = &quot;Строка&quot;, то компилятор понимает ее так: 1) char...

Как правильно возвращать строковый литерал из функции - C++
Строковый литерал по сути представляет собой указатель на данные. Но что если литерал был создан внутри функции и его значение вернуть?...

Строковый литерал и указатель на строку. В чем разница? - C++
Добрый день. Начал только изучать С++, не могу понять в чем разница между указателем на литерал и указателем на строку??? Заранее...

Как в макросе передать параметр в строковый литерал? - C++
Как в макросе передать параметр в строковый литерал? #define f(s) &quot;left##s##right&quot; не работает. Т.к. по команде cout &lt;&lt;...

"воткнуть" строковый литерал в поток ввода - C++
Подскажите, пожалуйста, как по-быстрому воткнуть строковый литерал в поток ввода? Нужно для тестирования просто, а разбираться со...

Локальный указатель на локальный строковый литерал - C++
Здравствуйте. Подскажите, пожалуйста, почему локальный указатель, созданный в функции, не уничтожается после вызова функции? То есть мы...

26
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
06.02.2014, 18:10 #2
Цитата Сообщение от mariko_11 Посмотреть сообщение
Не будет ли такой проблемы, что после выходе из конструктора в память, где ранее хранилось "ne erunda li?\0", будет записано что-то ещё?
нет
Цитата Сообщение от mariko_11 Посмотреть сообщение
Кстати, компилятор выдаёт предупреждение с указанием на строчку, где объявляется объект:
строковые литералы неизменяемы, поэтому к char * приводить нельзя, можно к char const*
0
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
06.02.2014, 18:13 #3
Попробуйте так.
C++
myClass(const char *s)
{
    strcpy(str,s);
}
Добавлено через 2 минуты
или так:
C++
myClass a((char*)"ne erunda li?");
0
Убежденный
Системный программист
Эксперт С++
15684 / 7194 / 1136
Регистрация: 02.05.2013
Сообщений: 11,630
Записей в блоге: 1
Завершенные тесты: 1
06.02.2014, 18:28 #4
Цитата Сообщение от mariko_11 Посмотреть сообщение
Сколько живёт строковый литерал?
В стандарте языка (C++98 2.13.4 String literals) сказано, что строковой
литерал имеет статическое время жизни (static storage duration).
1
Black Fregat
1392 / 1023 / 228
Регистрация: 31.05.2009
Сообщений: 4,274
06.02.2014, 18:36 #5
Или проставить в классе const
C++
1
2
3
4
5
6
7
8
9
class myClass
{
public:
    myClass(char const *s){str=s;}
    void print() {cout << str << endl;}
 
private:
    char const *str;
};
1
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,117
Записей в блоге: 5
Завершенные тесты: 1
06.02.2014, 18:43 #6
Цитата Сообщение от programina Посмотреть сообщение
Попробуйте так.
Так не пробуйте. Уж лучше вот так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class myClass
{
    public:
    myClass(const char *s)
    {
        str = new char[strlen(s) + 1];
        strcpy(str,s);
        str[strlen(s)] = '\0';
    }
    myClass(const myClass&);
    void print() {cout << str << endl;}
    ~myClass()
    {
        delete [] str;
    }
 
private:
    char const *str;
};
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,293
06.02.2014, 20:09 #7
Тоже не очень, обретем проблемы с копированием и последующим двойным удалением. Лучший вариант именно такого подхода - внутри держать std::string какой-нибудь. Либо запретить копирование вообще. Либо реализовать одну из семантик передачи владения.
0
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:18  [ТС] #8
Цитата Сообщение от Ilot Посмотреть сообщение
Так не пробуйте. Уж лучше вот так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class myClass
{
    public:
    myClass(const char *s)
    {
        str = new char[strlen(s) + 1];
        strcpy(str,s);
        str[strlen(s)] = '\0';
    }
    myClass(const myClass&);
    void print() {cout << str << endl;}
    ~myClass()
    {
        delete [] str;
    }
 
private:
    char const *str;
};
Чем именно лучше? В учебниках встречается такой способ, но почему именно он ? Чем хуже сделать явное приведение (char *)"ne erunda li?"? Это вот будет создана копия что ли или чо, просто пытаемся обуть компилятор и получаем доступ к той самой строчке-литералу?

Добавлено через 6 минут
Почему приводятся примеры с динамическим распределением памяти, а не тупо как у Black Fregat - поставить const и радоваться (а йадураг, не дошло так сделать-то...)?

Добавлено через 46 секунд
Цитата Сообщение от Убежденный Посмотреть сообщение
В стандарте языка (C++98 2.13.4 String literals) сказано, что строковой
литерал имеет статическое время жизни (static storage duration).
А в современном? Стандарт недавно поменялся. Кто-нибудь знает, ихде там это написано?
0
Croessmah
Эксперт CЭксперт С++
13509 / 7667 / 866
Регистрация: 27.09.2012
Сообщений: 18,864
Записей в блоге: 3
Завершенные тесты: 1
06.02.2014, 22:19 #9
Цитата Сообщение от mariko_11 Посмотреть сообщение
Почему приводятся примеры с динамическим распределением памяти, а не тупо как у Black Fregat - поставить const и радоваться (а йадураг, не дошло так сделать-то...)?
потому что там попытка скрутить с болта уже открученную гайку, да и как это сделать, если эта гайка на самом деле и не гайка а шайба?
0
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:20  [ТС] #10
Цитата Сообщение от Croessmah Посмотреть сообщение
потому что там попытка скрутить с болта уже открученную гайку, да и как это сделать, если эта гайка на самом деле и не гайка а шайба?
Что именно плохо? Какие нежелательные последствия могут быть, если так делать?
0
Croessmah
Эксперт CЭксперт С++
13509 / 7667 / 866
Регистрация: 27.09.2012
Сообщений: 18,864
Записей в блоге: 3
Завершенные тесты: 1
06.02.2014, 22:28 #11
Цитата Сообщение от mariko_11 Посмотреть сообщение
Какие нежелательные последствия могут быть, если так делать?
Никаких, если использовать так как можно, а не так как нельзя. Кто его знает что Вы там мудрите, может такой подход наиболее оправдан

Добавлено через 3 минуты
Цитата Сообщение от mariko_11 Посмотреть сообщение
Кто-нибудь знает, ихде там это написано?
это?
Цитата Сообщение от 2.14.5.8
Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).
0
DrOffset
7351 / 4451 / 1009
Регистрация: 30.01.2014
Сообщений: 7,293
06.02.2014, 22:31 #12
Цитата Сообщение от mariko_11 Посмотреть сообщение
Чем именно лучше? В учебниках встречается такой способ, но почему именно он ? Чем хуже сделать явное приведение (char *)"ne erunda li?"? Это вот будет создана копия что ли или чо, просто пытаемся обуть компилятор и получаем доступ к той самой строчке-литералу?
Строку по char* можно менять, но литерал менять нельзя, потому что он константа. Выдается warning именно в связи с этим.

Цитата Сообщение от mariko_11 Посмотреть сообщение
Почему приводятся примеры с динамическим распределением памяти, а не тупо как у Black Fregat - поставить const и радоваться (а йадураг, не дошло так сделать-то...)?
Потому что на основной вопрос уже ответили и люди стали предлагать другие варианты.

Цитата Сообщение от mariko_11 Посмотреть сообщение
А в современном? Стандарт недавно поменялся. Кто-нибудь знает, ихде там это написано?
2.14.5/8:
Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow
string literal has type “array of n const char”, where n is the size of the string as defined below, and has
static storage duration (3.7).
0
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:36  [ТС] #13
Цитата Сообщение от Croessmah Посмотреть сообщение
Никаких, если использовать так как можно, а не так как нельзя. Кто его знает что Вы там мудрите, может такой подход наиболее оправдан
О б-же. А чего ж тут можно намудрить, если просто сделать str константным (ну и соотв. параметр в конструкторе тоже)? Я даже и придумать-то такого не могу. Имеется в виду, что может занадобиться менять строку, а нельзя? Но тут-то компилятор просигналит, так что даже и не страшно. Или о чём речь?

Цитата Сообщение от Croessmah Посмотреть сообщение
это?
Ага, оно. По поводу периода хранения вопрос снят, всем спасибо. Осталось - а почему нельзя с const.

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что на основной вопрос уже ответили и люди стали предлагать другие варианты.
Вопрос был, почему это везде в учебниках, а вариант с const не встречается, хотя вроде проще и экономичнее. А ещё на способ с const выше наругались, вот я и выясняю, чего плохого.
0
Croessmah
Эксперт CЭксперт С++
13509 / 7667 / 866
Регистрация: 27.09.2012
Сообщений: 18,864
Записей в блоге: 3
Завершенные тесты: 1
06.02.2014, 22:37 #14
Цитата Сообщение от mariko_11 Посмотреть сообщение
Имеется в виду, что может занадобиться менять строку, а нельзя?
нельзя писать в литерал, это UB.
По сути, если перевести всё на целочисленные литералы, то получится что-то вроде
C++
1
6 = 33 ;
хорошо получается?
0
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:39  [ТС] #15
Цитата Сообщение от Croessmah Посмотреть сообщение
нельзя писать в литерал
Таки знаю, что нельзя. То есть, везде примеры с динамическим выделением памяти и копированием литерала в изменяемую строку, потому что может потребоваться её менять? Именно из-за этого не используется вариант с const char *?
0
06.02.2014, 22:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.02.2014, 22:39
Привет! Вот еще темы с ответами:

Дан строковый файл. Создать новый строковый файл, содержащий все строки исходного файла наименьшей длины (в том же порядке). - C++
Даны имена двух файлов вещественных чисел. Известно, что первый из них существует и является непустым, а второй в текущем каталоге...

Передать литерал функции - C++
Когда я создаю объект string, я могу написать так: string str = &quot;qwerty&quot;; // или string str(&quot;qwerty&quot;); // не суть //...

Что такое широкий литерал? - C++
Что такое широкий литерал? Объясните новичку. Совсем недавно решил изучать C++ по книге

Литерал - что делать с указателем? - C++
Недавно увидел нечто подобное. Раньше считал, что литерал может быть преобразован только в char - т.е. храниться на стеке, а там уже в...


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

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

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