Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
2 / 2 / 1
Регистрация: 11.03.2013
Сообщений: 64
1

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

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

Author24 — интернет-сервис помощи студентам
Имеется код
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.02.2014, 18:00
Ответы с готовыми решениями:

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

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

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

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

26
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
06.02.2014, 23:28 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от DrARTI Посмотреть сообщение
Я, конечно, очень люблю, когда мне отвечают, но тут слишком многобукафф. Может, получится по-конкретнее немного? Кусок кода там, или синопсис какой-нибудь, не знаю. Я ведь со своим знанием плюсов не пойму иначе ничерта.
Я просто привел ссылку на один из самых авторитетных источников, чтобы не было сомнений в том, что я говорю
Можно концепцию проиллюстрировать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class string_view
{
public:
    typedef char const *   iterator;
    typedef const iterator const_iterator;
 
    string_view(char const * str, size_t len);
    string_view(const_iterator begin, const_iterator end);
    string_view();
 
    const_iterator begin() const;
    const_iterator end() const;
 
    size_t size() const; 
 
    string_view substr(size_t start, size_t len = -1) const;
 
private:
    char const * begin_;
    char const * end_;
};
Представим, что у нас есть некий большой буфер, содержащий строку, которую надо парсить на подстроки. Так как нам нужно данные только читать, то такое решение идеально подойдет. В отличие от обычной строки тут нет расходов на копирование и выделение памяти для подстрок. Каждая подстрока просто "вырезанное" представление части более общей строки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char buf[size] = "very long string for parsing";
 
some_parsing_algo(string_view(buf, size));
//.....
 
void some_parsing_algo(string_view const & str)
{
// все STL алгоритмы с итераторами будут работать
// найдем первый пробел
    string_view::const_iterator space = std::find(str.begin(), str.end(), ' ');
    if(space != str.end())
    {
         // получим подстроку "very"
         string_view sub = str.substr(0, std::distance(str.begin(), space));
    }
}
Реализация методов string_view тривиальна.
Естественно тут нужно следить за временем жизни буфера, который используется в таком представлении.
1
0 / 1 / 0
Регистрация: 25.04.2013
Сообщений: 6
07.02.2014, 00:37 22
DrOffset, очень интересный код, благодарствую!

Добавлено через 15 минут
Сохранил даже, будет полезно в роли примера.
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
07.02.2014, 11:21 23
Цитата Сообщение от DrOffset Посмотреть сообщение
Тоже не очень, обретем проблемы с копированием и последующим двойным удалением. Лучший вариант именно такого подхода - внутри держать std::string какой-нибудь. Либо запретить копирование вообще. Либо реализовать одну из семантик передачи владения.
Смотрим на эту строчку:
C++
1
    myClass(const myClass&);
Объявление конструктора копирования без его определения это и есть запрет копирования.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
07.02.2014, 12:33 24
Цитата Сообщение от Ilot Посмотреть сообщение
это и есть запрет копирования.
который сработает только на стадии линковки...
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
07.02.2014, 13:43 25
Цитата Сообщение от Ilot Посмотреть сообщение
Смотрим на эту строчку:
C++
1
    myClass(const myClass&);
Объявление конструктора копирования без его определения это и есть запрет копирования.
Запретом копирования это было бы будь оно в привате. Либо, в рамках нового стандарта объявлено как
C++
1
myClass(const myClass&) = delete;
0
Эксперт по математике/физикеЭксперт С++
2048 / 1366 / 395
Регистрация: 16.05.2013
Сообщений: 3,506
Записей в блоге: 6
07.02.2014, 14:02 26
DrOffset, тогда попрбуйте скомпилировать такой код:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A{
    int a;
public:
    A(int a1): a(a1)
    {}
    A(const A&);
};
int main()
{
    A obj1(11);
    A obj2 = obj1;
 
    return 0;
}

Croessmah, как бы мысль понял. А как это проверить на стадии выполнения программы? Не совсем понимаю. Пусть даже компилятор пропустит код без определения конструктора все равно во время выполнения программы произойдет обращение к несуществующей функции и по идее программа должна "слететь". Так? Т.е. другими словами копирования объектов все-равно не произойдет?
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
07.02.2014, 14:12 27
Цитата Сообщение от Ilot Посмотреть сообщение
DrOffset, тогда попрбуйте скомпилировать такой код:
Croessmah, как бы мысль понял.
Кажется с его стороны это был сарказм. Код, который вы дали приводит к unresolved external во время линковки. Croessmah и я вам как бы намекали, что это слишком поздно и неплохо бы это отловить еще на этапе компиляции! Для этого сейчас в новом стандарте есть стандартное средство.

Цитата Сообщение от Ilot Посмотреть сообщение
А как это проверить на стадии выполнения программы? Не совсем понимаю. Пусть даже компилятор пропустит код без определения конструктора все равно во время выполнения программы произойдет обращение к несуществующей функции и по идее программа должна "слететь". Так? Т.е. другими словами копирования объектов все-равно не произойдет?
Не нужно проверять на этапе выполнения Прочитайте еще раз пожалуйста мое предыдущее сообщение. Чтобы запретитькопирование с диагностикой на этапе компиляции в С++98 и С++03 конструктор копирования помещают в приват без реализации. См. например boost::noncopyable. В С++11 для запрещения каких либо операций с классом ввели стандартное средство, которое я демонстрировал
1
07.02.2014, 14:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2014, 14:12
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru