13.7.3 Временные объекты могут исчезнуть раньше, чем вы ожидаете
Опасно использовать указатели или ссылки на части временного объекта. Компилятор может удалить объект раньше, чем вы ожидаете, оставив указатель на мусор. Эта проблема чаще всего возникает в классах, таких как классы строк, особенно в тех, которые определяют функцию преобразования в тип char * или const char *—это одна из причин, почему стандартный класс string требует вызова члена c_str.
Например, программа может использовать функцию strfunc, которая возвращает объекты string, и другую функцию charfunc, которая работает с указателями на char:
string strfunc ();
void charfunc (const char *);
void
f ()
{
const char *p = strfunc().c_str();
…
charfunc (p);
…
charfunc (p);
}
В этой ситуации может показаться разумным сохранить указатель на строку C, возвращаемую членом c_str, и использовать его вместо повторного вызова c_str. Однако временная строка, созданная вызовом strfunc, уничтожается после инициализации p, в результате чего p указывает на освобожденную память.
Код такого типа может работать успешно под некоторыми другими компиляторами, особенно устаревшими компиляторами на основе cfront, которые удаляют временные объекты вместе с обычными локальными переменными. Однако поведение GNU C++ соответствует стандарту, поэтому если ваша программа зависит от позднего уничтожения временных объектов, она не будет портабельной.
Безопасный способ написания такого кода — дать временному объекту имя, что заставит его сохраниться до конца области видимости имени. Например:
const string& tmp = strfunc (); charfunc (tmp.c_str ());
Далее: Копирующая инициализация, Предыдущее: Поиск имен, Вверх: Ошибки в C++ [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Temporaries.html