Является ли это хорошим стилем для разыменования "нового" указателя? - программирование
Подтвердить что ты не робот

Является ли это хорошим стилем для разыменования "нового" указателя?

Чтобы избежать необходимости использовать -> и вместо этого работать непосредственно с объектом, допустимо ли это делать:

obj x = *(new obj(...));
...
delete &obj;
4b9b3361

Ответ 1

Это не просто плохая практика, но:

  • Утечка памяти (скорее всего, если вы не используете какой-либо шаблон, который не отображается из кода, который вы предоставили), так как obj будет хранить копию исходного объекта, созданного выражением new, и указатель на этот объект, возвращенный new, будет потерян;
  • Самое главное, undefined поведение, так как вы передаете delete указатель на объект, который не был выделен new. В пункте 5.3.5/2 стандарта С++ 11:

[...] В первом альтернативе (удалить объект) значение операнда удаления может быть нулевым указателем value, указатель на объект без массива, созданный предыдущим новым выражением, или указатель на подобъект (1.8) представляющий базовый класс такого объекта (п. 10). Если нет, поведение undefined.

Ответ 2

Нет, и на самом деле это приводит к утечке. x копируется инициализировано, поэтому исходный объект, на который указывает new obj, теряется.

Просто используйте

obj x(...);

Нет необходимости динамического выделения. Или

obj x = obj(...);

если вы должны (сомневайтесь).

Ответ 3

Конечно, нет; который копирует динамический объект в автоматическую переменную, теряет единственный указатель на него, а затем пытается удалить автоматическую копию. У вас есть утечка памяти и неправильное удаление.

Намного лучше было бы использовать автоматическую переменную в первую очередь:

obj x(...);
...
// no need to delete anything

или, если по какой-то причине он действительно должен быть динамическим (потому что он слишком велик для стека, или вы не всегда хотите его уничтожить), затем используйте умный указатель и ссылку, t like ->

std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything

Изменение вашего x в ссылке будет действительным (если вы будете осторожны, что исключения, ранняя функция возвращается и т.д. не вызовет утечку), но вызовет вопли путаницы среди всех, кому не хватает должны поддерживать его.

Ответ 4

Вы не можете удалить свой объект должным образом, если вы это сделаете.

Неявно вы делаете следующее.

class A
{
public:
  int test (void) { return 1; }
};

int main (void)
{
  A * p = new A;
  A v(*p);
  //...
  delete &v; // &v != p and v is not constructed via new!
  return 0;
}

Если вы хотите работать с похожим на объект синтаксисом, вы можете привязать ссылку к объекту.

class A
{
public:
  int test (void) { return 1; }
};

int main (void)
{
   A * p = new A;
   A & r = *p;
   int i = r.test();
   delete p;
   return 0;
}

Если вы удаляете свой объект с помощью одного и того же указателя, утечки не будет.