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-8.5.0/gcc/Temporaries.html