对堆栈上分配的变量调用删除
-
22-07-2019 - |
题
忽略编程风格和设计,对堆栈上分配的变量调用删除是否“安全”?
例如:
int nAmount;
delete &nAmount;
或者
class sample
{
public:
sample();
~sample() { delete &nAmount;}
int nAmount;
}
解决方案
不, 打电话不安全 delete
在堆栈分配的变量上。你应该只打电话 delete
在创造的事物上 new
.
- 对于每个
malloc
或者calloc
, 应该正好有一个free
. - 对于每个
new
应该正好有一个delete
. - 对于每个
new[]
应该正好有一个delete[]
. - 对于每个堆栈分配,不应有显式释放或删除。如果适用,析构函数会自动调用。
一般来说,您不能混合和匹配其中任何一个,例如不 free
-ing 或 delete[]
-ing a new
目的。这样做会导致未定义的行为。
其他提示
好了,让我们来试试吧:
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
因此很明显,这是不是安全的。
请记住,当你分配内存使用新的块(或malloc的为此事),分配的内存块实际会比你的要求较大。 存储器块也将包含一些记录信息,以便当您释放块,它可以很容易地放回空闲池并且可能与相邻的空闲块被合并。
当您尝试释放,你没有从新收到任何记忆,即簿记信息不会在那里,但系统将像它,结果将是不可预知的(通常是坏)。
是的,这是不确定的行为:传递给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&)
在标准库的先前调用的返回值中的一个。
的未定义的行为的后果是,很好,未定义。 “什么也没有发生”是为有效结果为别的。然而,它通常是“什么也没发生的时候了”。重新分配一个无效的内存块可能在后续调用分配的严重后果
在 Windows 中玩了一下 g++ 4.4 后,我得到了非常有趣的结果:
对堆栈变量调用删除似乎没有执行任何操作。没有抛出错误,但删除后我可以毫无问题地访问该变量。
有一个带有方法的类
delete this
如果对象在堆中分配,则成功删除该对象,但如果在堆栈中分配,则不会成功删除该对象(如果在堆栈中,则不会发生任何情况)。
没人能知道会发生什么。这调用未定义行为,所以从字面上任何事情都有可能发生。 别这样做。
没有, 使用新分配的内存应该使用delete运算符删除 而使用malloc分配应该使用免费删除。 并没有必要解除分配其上堆栈分配的变量。
这是天使失去了翅膀......你只能调用delete
与new
分配的指针,否则,你得到了一个未定义的行为。
这里的内存使用栈故无需exernally删除分配,但如果你已经动态allcoted
像 INT * A =新INT()
然后你要做的删除,而不是删除&A(A本身是一个指针),因为内存是从自由存储分配。
您已经回答了自己的问题。 delete
只能用于通过new
optained指针。做别的事情是简单明了的未定义的行为。
因此确实没有说发生什么事,从通过轰然删除你的硬盘做工精细的代码什么是这样做的结果有效。所以,请的从来没有做到这一点的。
这是因为UB你不能调用删除已经没有新的被动态分配的项目。就这么简单。