Spec-Zone.ru › GCC 10

Далее: Неявная копирующая инициализация для виртуальных баз, Предыдущее: Поиск имен, шаблоны и доступ к членам базовых классов, Вверх: Распространённые недоразумения с GNU C++ [Содержание][Индекс]

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

Далее: Неявная копирующая инициализация для виртуальных баз, Предыдущее: Поиск имен, шаблоны и доступ к членам базовых классов, Вверх: Распространённые недоразумения с GNU C++ [Содержание][Индекс]

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

Spec-Zone.ru

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