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

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

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

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

06.02.2014, 18:00. Просмотров 1018. Ответов 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?");
^
Как можно это обойти с минимальными изменениями кода класса?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2014, 18:00     Сколько живёт строковый литерал?
Посмотрите здесь:

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

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

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

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

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

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

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

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
1411 / 1140 / 55
Регистрация: 21.04.2012
Сообщений: 2,362
Завершенные тесты: 3
06.02.2014, 18:10     Сколько живёт строковый литерал? #2
Цитата Сообщение от mariko_11 Посмотреть сообщение
Не будет ли такой проблемы, что после выходе из конструктора в память, где ранее хранилось "ne erunda li?\0", будет записано что-то ещё?
нет
Цитата Сообщение от mariko_11 Посмотреть сообщение
Кстати, компилятор выдаёт предупреждение с указанием на строчку, где объявляется объект:
строковые литералы неизменяемы, поэтому к char * приводить нельзя, можно к char const*
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?");
Убежденный
Системный программист
Эксперт С++
15239 / 6871 / 1088
Регистрация: 02.05.2013
Сообщений: 11,253
Завершенные тесты: 1
06.02.2014, 18:28     Сколько живёт строковый литерал? #4
Цитата Сообщение от mariko_11 Посмотреть сообщение
Сколько живёт строковый литерал?
В стандарте языка (C++98 2.13.4 String literals) сказано, что строковой
литерал имеет статическое время жизни (static storage duration).
Black Fregat
1368 / 998 / 217
Регистрация: 31.05.2009
Сообщений: 4,182
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;
};
Ilot
Модератор
Эксперт С++
1789 / 1164 / 226
Регистрация: 16.05.2013
Сообщений: 3,060
Записей в блоге: 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;
};
DrOffset
6912 / 4105 / 933
Регистрация: 30.01.2014
Сообщений: 6,903
06.02.2014, 20:09     Сколько живёт строковый литерал? #7
Тоже не очень, обретем проблемы с копированием и последующим двойным удалением. Лучший вариант именно такого подхода - внутри держать std::string какой-нибудь. Либо запретить копирование вообще. Либо реализовать одну из семантик передачи владения.
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).
А в современном? Стандарт недавно поменялся. Кто-нибудь знает, ихде там это написано?
Croessmah
Модератор
Эксперт CЭксперт С++
12979 / 7291 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 3
Завершенные тесты: 1
06.02.2014, 22:19     Сколько живёт строковый литерал? #9
Цитата Сообщение от mariko_11 Посмотреть сообщение
Почему приводятся примеры с динамическим распределением памяти, а не тупо как у Black Fregat - поставить const и радоваться (а йадураг, не дошло так сделать-то...)?
потому что там попытка скрутить с болта уже открученную гайку, да и как это сделать, если эта гайка на самом деле и не гайка а шайба?
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:20  [ТС]     Сколько живёт строковый литерал? #10
Цитата Сообщение от Croessmah Посмотреть сообщение
потому что там попытка скрутить с болта уже открученную гайку, да и как это сделать, если эта гайка на самом деле и не гайка а шайба?
Что именно плохо? Какие нежелательные последствия могут быть, если так делать?
Croessmah
Модератор
Эксперт CЭксперт С++
12979 / 7291 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 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).
DrOffset
6912 / 4105 / 933
Регистрация: 30.01.2014
Сообщений: 6,903
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).
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:36  [ТС]     Сколько живёт строковый литерал? #13
Цитата Сообщение от Croessmah Посмотреть сообщение
Никаких, если использовать так как можно, а не так как нельзя. Кто его знает что Вы там мудрите, может такой подход наиболее оправдан
О б-же. А чего ж тут можно намудрить, если просто сделать str константным (ну и соотв. параметр в конструкторе тоже)? Я даже и придумать-то такого не могу. Имеется в виду, что может занадобиться менять строку, а нельзя? Но тут-то компилятор просигналит, так что даже и не страшно. Или о чём речь?

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

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что на основной вопрос уже ответили и люди стали предлагать другие варианты.
Вопрос был, почему это везде в учебниках, а вариант с const не встречается, хотя вроде проще и экономичнее. А ещё на способ с const выше наругались, вот я и выясняю, чего плохого.
Croessmah
Модератор
Эксперт CЭксперт С++
12979 / 7291 / 812
Регистрация: 27.09.2012
Сообщений: 18,007
Записей в блоге: 3
Завершенные тесты: 1
06.02.2014, 22:37     Сколько живёт строковый литерал? #14
Цитата Сообщение от mariko_11 Посмотреть сообщение
Имеется в виду, что может занадобиться менять строку, а нельзя?
нельзя писать в литерал, это UB.
По сути, если перевести всё на целочисленные литералы, то получится что-то вроде
C++
1
6 = 33 ;
хорошо получается?
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 22:39  [ТС]     Сколько живёт строковый литерал? #15
Цитата Сообщение от Croessmah Посмотреть сообщение
нельзя писать в литерал
Таки знаю, что нельзя. То есть, везде примеры с динамическим выделением памяти и копированием литерала в изменяемую строку, потому что может потребоваться её менять? Именно из-за этого не используется вариант с const char *?
DrOffset
6912 / 4105 / 933
Регистрация: 30.01.2014
Сообщений: 6,903
06.02.2014, 22:44     Сколько живёт строковый литерал? #16
Цитата Сообщение от mariko_11 Посмотреть сообщение
Таки знаю, что нельзя. То есть, везде примеры с динамическим выделением памяти и копированием литерала в изменяемую строку, потому что может потребоваться её менять? Именно из-за этого не используется вариант с const char *?
И поэтому тоже. А в том примере, на который заругались, был strcpy в невыделенную память, что есть UB.
Вот так нельзя, потому что p это только указатель, а не строка, в данном случае он даже ни на что не указывает. Попытка проведения этой операции скорее всего закончится крахом программы. Поэтому человек и заменил этот пример, на тот, где память выделяется, соответственно и копирование становится возможным.
C++
1
2
char * p;
strcpy(p, "test");
DrARTI
0 / 1 / 0
Регистрация: 25.04.2013
Сообщений: 6
06.02.2014, 22:45     Сколько живёт строковый литерал? #17
Цитата Сообщение от Black Fregat Посмотреть сообщение
Или проставить в классе 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;
};
>>myClass(char const *s){str=s;}
Ну идея-то, конечно, верная, но есть рациональный вопрос: а зачем? То есть, например, чисто на практике, как это вообще сможет пригодиться?
ОП, вопрос у тебя изначально странный очень. На то литерал и литерал, чтобы быть константой (ну т.е. относительно бессмертным), нет? Ну а если ты делаешь его копию в виде переменной (про ссылку на константу пока молчу), то, очевидно, время жизни этой копии уже будет независимо от времени жизни литерала?
DrOffset
6912 / 4105 / 933
Регистрация: 30.01.2014
Сообщений: 6,903
06.02.2014, 22:58     Сколько живёт строковый литерал? #18
Цитата Сообщение от DrARTI Посмотреть сообщение
>>myClass(char const *s){str=s;}
Ну идея-то, конечно, верная, но есть рациональный вопрос: а зачем? То есть, например, чисто на практике, как это вообще сможет пригодиться?
Запросто может пригодиться (немного не в таком виде, но схожем), для оптимизации например. Вот пример.
Сам использовал похожий класс в большом проекте для представления подстрок. Помогло избежать оверхеда по выделению памяти и копированию строк. Но граничные условия разумеется надо знать, подход не везде применим.
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 23:03  [ТС]     Сколько живёт строковый литерал? #19
Цитата Сообщение от DrOffset Посмотреть сообщение
И поэтому тоже. А в том примере, на который заругались, был strcpy в невыделенную память, что есть UB.
Вот так нельзя, потому что p это только указатель, а не строка, в данном случае он даже ни на что не указывает. Попытка проведения этой операции скорее всего закончится крахом программы. Поэтому человек и заменил этот пример, на тот, где память выделяется, соответственно и копирование становится возможным.
C++
1
2
char * p;
strcpy(p, "test");
Да не, я про то, что ругались на вариант с const. Что в невыделенную память нехорошо копировать, я в курсе.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.02.2014, 23:05     Сколько живёт строковый литерал?
Еще ссылки по теме:

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

Строквой литерал в двоичном представлении - C++
Добрый день. В учебнике есть задание: составить пользовательский тип который может вместить значение факториала числа 1000 с абсолютной...

Литерал это значение любой переменой, ведь так ? - C++
Добрый вечер. По ходу изучения программирования скопилось немало вопросов, к которым периодически приходится возвращаться. Поэтому...

Какое получается значение и тип имеет литерал 3.14e1L - C++
3.14e1L Какое получается значение и тип? смущает суффикс e

Строковый анализатор - C++
Подскажите почему код выдает всякий мусор, подает звуковые сигналы Должен работать так: Если введешь так: &quot;11/23/34&quot; или &quot;11.23.34&quot;...


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

Или воспользуйтесь поиском по форуму:
DrARTI
0 / 1 / 0
Регистрация: 25.04.2013
Сообщений: 6
06.02.2014, 23:05     Сколько живёт строковый литерал? #20
Цитата Сообщение от DrOffset Посмотреть сообщение
Запросто может пригодиться (немного не в таком виде, но схожем), для оптимизации например. Вот пример.
Сам использовал похожий класс в большом проекте для представления подстрок. Помогло избежать оверхеда по выделению памяти и копированию строк. Но граничные условия разумеется надо знать, подход не везде применим.
Я, конечно, очень люблю, когда мне отвечают, но тут слишком многобукафф. Может, получится по-конкретнее немного? Кусок кода там, или синопсис какой-нибудь, не знаю. Я ведь со своим знанием плюсов не пойму иначе ничерта.
Yandex
Объявления
06.02.2014, 23:05     Сколько живёт строковый литерал?
Ответ Создать тему
Опции темы

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