Spec-Zone.ru › GCC 15

15.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 ());

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Temporaries.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API