У меня есть два вопроса о коде ниже

Запустив этот код в VS2010, я получаю предупреждения, показанные ниже, но C-строки «f ()» и «g ()» выводятся на консоли.

Вопрос 1: Почему f () генерирует предупреждение, а g () нет? Разве строковые литералы не хранятся в статической памяти до завершения программы?

Вопрос 2: Когда я закомментирую вызов h () в main (), код вылетает. Почему разное поведение?

#include<iostream>

const char* const& f()
{
return "f()";            //  warning C4172: returning address of local variable or temporary
}

const char* g()
{
return "g()";           //  no warning
}

const std::string& h()
{
return "h()";           //  warning C4172:
}

int main()
{
std::cout << f() << '\n';
std::cout << g() << '\n';
//  std::cout << h().c_str() << '\n';       //  comment out and program crashes
}

2

Решение

Вы возвращаете ссылка на значение, которое вы используете только локально. Это неопределенное поведение. То, что вы, вероятно, хотите, это просто вернуть указатель на символ или std::string, а не ссылка на указатель на символ или std::string&,

Тот факт, что вы видите f() распечатано только удача розыгрыша. Это все еще неопределенное поведение, и на него нельзя рассчитывать.

3

Другие решения

f () производит неопределенное поведение. Неопределенное поведение держит вашу программу в недопустимом состоянии, что приводит к (псевдослучайным) сбоям.

Это неопределенное поведение, потому что вы возвращаете ссылку на локальную переменную. После вызова функции локальная переменная будет уничтожена, оставляя ваши char* на самом деле указывает на никуда

Если вы удалите ссылку, значение будет скопировано, и у нас нет нарушения области действия.

2