调用删除栈上分配的变量(Calling delete on variable allocated o

2019-09-22 16:39发布

忽略的编程风格和设计,是“安全”来称呼删除在栈上分配的变量?

例如:

   int nAmount;
   delete &nAmount;

要么

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

Answer 1:

不 ,它不是安全地调用delete在栈上分配的变量。 您应该只调用delete对创造的东西new

  • 对于每个malloccalloc ,也应该只有一个free
  • 对于每一个new应该只有一个delete
  • 对于每一个new[]应该只有一个delete[]
  • 对于每个堆栈分配,应该是没有明确的释放或删除。 析构函数会自动在适用情况下调用。

在一般情况下,你不能随意搭配任何这些,例如,没有free -ing或delete[] -ing一个new对象。 这样做会导致不确定的行为。



Answer 2:

好吧,让我们试试吧:

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

因此很明显,这是不是安全的。



Answer 3:

请记住,当你分配内存使用新的(或内存分配为此事)块,分配的内存块实际会比你的要求较大。 该内存块也将包含一些记录信息,这样当你释放块,它可以很容易地放回空闲池,并可能与相邻的空闲块被合并。

当您尝试自由的时候并没有从新收到任何记忆,即簿记信息不会在那里,但系统将像它,结果将是不可预知的(通常是坏)。



Answer 4:

是的,这是不确定的行为:传递给delete任何不是来自new的UB:

C ++标准,节3.7.3.2.3:供给到在标准库可以是提供特亚解除分配功能中的一个的第一个参数的值null指针值; 如果是这样,并且如果释放函数是一个在标准库供给,该呼叫到释放函数没有影响。 否则,供给值operator delete(void*)标准库须由要么以前调用的返回值的一个operator new(std::size_t)operator new(std::size_t, const std::nothrow_t&)在标准库。

未定义行为的后果是,好了,不明确的。 “什么也没有发生”是为有效结果为别的。 然而,它通常是“什么也没发生的时候了”:重新分配一个无效的内存块可能在后续调用分配器严重的后果。



Answer 5:

打了一下使用g ++在Windows 4.4之后,我得到了非常有趣的结果:

  1. 调用删除堆栈变量似乎并没有做任何事情。 没有错误抛出,但删除后,我可以访问变量没有问题。

  2. 有一个类的方法与delete this成功删除对象如果在堆中分配,但如果它在堆栈中分配(如果是在栈中,没有任何反应)。



Answer 6:

没有人能知道会发生什么。 这调用未定义行为,所以从字面上任何事情都有可能发生。 不要这样做。



Answer 7:

不,内存使用新应使用delete运算符删除,使用malloc分配应该使用免费删除分配。 而且不需要撤销分配其在堆栈中分配的变量。



Answer 8:

一位天使失去了翅膀......你只能调用delete与分配的指针new ,否则,你得到了一个未定义的行为。



Answer 9:

这里的内存使用栈故无需exernally删除分配,但如果你已经动态allcoted

如int * A =新INT()

然后你要做的删除,而不是删除&A(A本身是一个指针),因为内存是从自由存储分配。



Answer 10:

你已经自己回答了这个问题。 delete只能用于通过optained指针new 。 做别的事情是简单明了的未定义的行为。

因此确实没有说发生什么事,什么都从通过轰然删除你的硬盘做工精细的代码是这样做的一个有效成果。 所以,请永远不要这样做



Answer 11:

这是因为UB你一定不要称呼还没有新的被动态分配的项目删除。 就这么简单。



文章来源: Calling delete on variable allocated on the stack