Колко дълго живее низова константа в c++?

Чудех се колко дълго живее низова константа в C++. Например, ако създам някакъв const char *str = "нещо" вътре във функция, ще бъде ли безопасно да върна стойността на str?

Написах примерна програма и бях наистина изненадан да видя, че такава върната стойност все още съхранява този низ. Ето кода:

#include <iostream>
using namespace std;

const char *func1()
{
    const char *c = "I am a string too";
    return c;
}

void func2(const char *c = "I'm a default string")
{
    cout << c << endl;
}

const int *func3()
{
    const int &b = 10;
    return &b;
}

int main()
{
    const char *c = "I'm a string";
    cout << c << endl;
    cout << func1() << endl;
    func2();
    func2("I'm not a default string");
    cout << *func3() << endl;
    return 0;
}

Дава ми следния изход:

Аз съм струна

И аз съм струна

Аз съм низ по подразбиране

Аз не съм низ по подразбиране

10

Func3 е там само за да разбере дали същото работи с други типове.
Така че въпросът е: безопасно ли е да се върне указател към низова константа, създадена в тази функция (както в func1())?
Също така, безопасно ли е да се използва стойността на низа по подразбиране, както във func2()?


person SiLiKhon    schedule 15.07.2014    source източник
comment
Ако е в кавички, живее вечно.   -  person Neil Kirk    schedule 15.07.2014
comment
int j = 2; -- колко дълго живеят тези 2? Ако можехте да направите int const *j = &2;, отговорът пак щеше да е същият.   -  person David Schwartz    schedule 16.07.2014


Отговори (1)


Низовият литерал има продължителност на статичното съхранение и продължава живота на програмата. От проект на C++ стандарт раздел 2.14.5 Низови литерали параграф 8, който казва (акцентът е мой за напред):

Обикновените низови литерали и UTF-8 низови литерали също се наричат ​​тесни низови литерали. Тесният низов литерал има тип „масив от n const char“, където n е размерът на низа, както е дефиниран по-долу, и има продължителност на статично съхранение (3.7).

и от раздел 3.7.1 Продължителност на статичното съхранение параграф 1:

Всички променливи, които нямат продължителност на динамично съхранение, нямат продължителност на съхранение на нишки и не са локални, имат продължителност на статично съхранение. Съхранението за тези обекти трябва да продължи за продължителността на програмата (3.6.2, 3.6.3).

Вторият случай в func3 от друга страна не е валиден. Животът на временно обвързана с препратка продължава за живота на препратката, който в този случай приключва, когато функцията се върне. Това е описано в раздел 12.2, който казва:

Вторият контекст е, когато препратка е обвързана с временен обект.115 Временният елемент, към който е обвързана препратката, или временният обект, който е пълен обект на подобект, към който е обвързана препратката, продължава за целия живот на препратката с изключение на:

person Shafik Yaghmour    schedule 15.07.2014
comment
Или завинаги, ако се съхранява в ROM. Искам да кажа, че указателят може да сочи навсякъде, дори в ROM. - person user1095108; 15.07.2014
comment
Благодаря много! А какво ще кажете за func3 тук? Очаква ли се върнатата му стойност да бъде валидна, след като функцията се върне към main? - person SiLiKhon; 15.07.2014
comment
@SiLiKhon Като цяло няма да работи. Можете да го видите, ако промените int на клас, който има деструктор, който извиква нещо като destructing, когато излиза извън обхвата, и ще видите, че обектът ще бъде унищожен, преди да извикате cout върху него. Във вашия пример паметта, в която живее това цяло число, все още не е презаписана, така че имате късмет, че отпечатва стойността, която очаквате. - person triple_r; 15.07.2014