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