Вызов удаления по переменной, выделенной в стеке

Игнорируя стиль и дизайн программирования, безопасно ли вызывать delete для переменной, выделенной в стеке?

Например:

   int nAmount;
   delete &nAmount;

или

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}
+46
14 янв. '09 в 3:41
источник поделиться
11 ответов

Нет, небезопасно вызывать delete в переменной, назначенной стеком. Вы должны называть только delete для объектов, созданных new.

  • Для каждого malloc или calloc должен быть ровно один free.
  • Для каждого new должен быть ровно один delete.
  • Для каждого new[] должен быть ровно один delete[].
  • Для каждого распределения стека не должно быть явного освобождения или удаления. Деструктор вызывается автоматически, где это применимо.

В общем, вы не можете смешивать и сопоставлять любые из них, например. no free -ing или delete[] -ing a new объект. Это приводит к поведению undefined.

+89
14 янв. '09 в 3:44
источник

Связанные вопросы


Похожие вопросы

Ну, попробуй:

jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault

Таким образом, очевидно, что это не безопасно.

+42
14 янв. '09 в 3:47
источник

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

Когда вы пытаетесь освободить любую память, которую вы не получили от новой, эта бухгалтерская информация не будет там, но система будет действовать так, как она есть, и результаты будут непредсказуемыми (как правило, плохими). ​​

+14
14 янв. '09 в 5:11
источник

Да, это поведение undefined: переход на delete все, что не исходило от new, - это UB:

Стандарт С++, раздел 3.7.3.2.3: Значение первого аргумента, предоставленного одной из функций дезадаптации, предоставляемых в стандартной библиотеке, может быть значением указателя null; если это так, и если функция освобождения включена в стандартную библиотеку, вызов функции освобождения не влияет. В противном случае значение, указанное в operator delete(void*) в стандартной библиотеке, должно быть одним из значений, возвращаемых предыдущим вызовом либо operator new(std::size_t), либо operator new(std::size_t, const std::nothrow_t&) в стандартной библиотеке.

Последствия поведения undefined - это, ну, undefined. "Ничто не происходит" не является столь же важным следствием, как и все остальное. Однако обычно "ничего не происходит сразу": освобождение недопустимого блока памяти может иметь серьезные последствия при последующих вызовах распределителя.

+7
20 сент. '12 в 13:19
источник

Поиграв немного с g++ 4.4 в windows, я получил очень интересные результаты:

  • вызов delete в переменной стека, похоже, ничего не делает. Нет ошибок, но я могу получить доступ к переменной без проблем после удаления.

  • Наличие класса с методом delete this успешно удаляет объект, если он выделен в куче, но не если он выделен в стеке (если он находится в стеке, ничего не происходит).

+6
17 мая '11 в 19:37
источник

Никто не знает, что происходит. Это вызывает поведение undefined, поэтому буквально все может случиться. Не делайте этого.

+5
20 сент. '12 в 13:18
источник

Нет, Память, выделенная с использованием нового, должна быть удалена с помощью оператора delete и что выделенное использование malloc следует удалить, используя бесплатный. И нет необходимости освобождать переменную, которая выделяется в стеке.

+4
14 янв. '09 в 10:02
источник

Ангел теряет свои крылья... Вы можете вызывать delete только указатель, выделенный с помощью new, иначе вы получите поведение undefined.

+3
20 сент. '12 в 13:19
источник

здесь память выделяется с помощью стека, поэтому нет необходимости ее удалять по-другому, но если вы динамически указали

как int * a = new int()

тогда вам нужно удалить a, а не delete & a (сам по себе указатель), поскольку память выделяется из свободного хранилища.

+1
14 янв. '09 в 10:28
источник

Вы уже сами ответили на вопрос. delete должен использоваться только для указателей, опережаемых через new. Выполнение всего остального - это простое и простое поведение undefined.

Таким образом, на самом деле нет никаких заявлений о том, что происходит, что-то из кода, работающего нормально, через сбой, чтобы стереть ваш жесткий диск, является правильным результатом этого. Поэтому никогда не делайте этого.

0
20 сент. '12 в 13:19
источник

Это UB, потому что вы не должны вызывать delete для элемента, который не был динамически выделен новым. Это просто.

0
20 сент. '12 в 13:19
источник

Посмотрите другие вопросы по меткам или Задайте вопрос