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

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

Восстановить пароль Регистрация
 
 
mariko_11
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
06.02.2014, 18:00     Сколько живёт строковый литерал? #1
Имеется код
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?");
^
Как можно это обойти с минимальными изменениями кода класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
06.02.2014, 18:10     Сколько живёт строковый литерал? #2
Цитата Сообщение от mariko_11 Посмотреть сообщение
Не будет ли такой проблемы, что после выходе из конструктора в память, где ранее хранилось "ne erunda li?\0", будет записано что-то ещё?
нет
Цитата Сообщение от mariko_11 Посмотреть сообщение
Кстати, компилятор выдаёт предупреждение с указанием на строчку, где объявляется объект:
строковые литералы неизменяемы, поэтому к char * приводить нельзя, можно к char const*
programina
 Аватар для programina
1912 / 597 / 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?");
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,296
Завершенные тесты: 1
06.02.2014, 18:28     Сколько живёт строковый литерал? #4
Цитата Сообщение от mariko_11 Посмотреть сообщение
Сколько живёт строковый литерал?
В стандарте языка (C++98 2.13.4 String literals) сказано, что строковой
литерал имеет статическое время жизни (static storage duration).
Black Fregat
 Аватар для Black Fregat
1353 / 983 / 215
Регистрация: 31.05.2009
Сообщений: 4,093
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
Модератор
Эксперт С++
1765 / 1140 / 221
Регистрация: 16.05.2013
Сообщений: 3,017
Записей в блоге: 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
6417 / 3791 / 876
Регистрация: 30.01.2014
Сообщений: 6,577
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
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,832
Записей в блоге: 2
Завершенные тесты: 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
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,832
Записей в блоге: 2
Завершенные тесты: 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
6417 / 3791 / 876
Регистрация: 30.01.2014
Сообщений: 6,577
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
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,832
Записей в блоге: 2
Завершенные тесты: 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
6417 / 3791 / 876
Регистрация: 30.01.2014
Сообщений: 6,577
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
6417 / 3791 / 876
Регистрация: 30.01.2014
Сообщений: 6,577
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++ Строквой литерал в двоичном представлении
Литерал - что делать с указателем? C++
C++ Передать литерал функции

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

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

Текущее время: 11:19. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru