Подтвердить что ты не робот

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

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

Например:

   int nAmount;
   delete &nAmount;

или

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}
4b9b3361

Ответ 1

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

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

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

Ответ 2

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

[email protected]:~$ echo 'main() { int a; delete &a; }' > test.cpp
[email protected]:~$ g++ -o test test.cpp
[email protected]:~$ ./test
Segmentation fault

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

Ответ 3

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

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

Ответ 4

Да, это поведение 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. "Ничто не происходит" не является столь же важным следствием, как и все остальное. Однако обычно "ничего не происходит сразу": освобождение недопустимого блока памяти может иметь серьезные последствия при последующих вызовах распределителя.

Ответ 5

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

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

как int * a = new int()

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

Ответ 10

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

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

Ответ 11

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