Запустив этот код в 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
}
Вы возвращаете ссылка на значение, которое вы используете только локально. Это неопределенное поведение. То, что вы, вероятно, хотите, это просто вернуть указатель на символ или std::string
, а не ссылка на указатель на символ или std::string&
,
Тот факт, что вы видите f()
распечатано только удача розыгрыша. Это все еще неопределенное поведение, и на него нельзя рассчитывать.
f () производит неопределенное поведение. Неопределенное поведение держит вашу программу в недопустимом состоянии, что приводит к (псевдослучайным) сбоям.
Это неопределенное поведение, потому что вы возвращаете ссылку на локальную переменную. После вызова функции локальная переменная будет уничтожена, оставляя ваши char*
на самом деле указывает на никуда
Если вы удалите ссылку, значение будет скопировано, и у нас нет нарушения области действия.