当前位置:  开发笔记 > 编程语言 > 正文

在堆栈上分配的变量上调用delete

如何解决《在堆栈上分配的变量上调用delete》经验,为你挑选了6个好方法。

忽略编程风格和设计,在堆栈上分配的变量上调用delete是"安全的"吗?

例如:

   int nAmount;
   delete &nAmount;

要么

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

Mr Fooz.. 102

不,调用delete堆栈分配的变量是不安全的.你应该只调用delete创建的东西new.

对于每个malloc或者calloc,应该只有一个free.

每个new应该只有一个delete.

每个new[]应该只有一个delete[].

对于每个堆栈分配,应该没有明确的释放或删除.在适用的情况下,会自动调用析构函数.

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



1> Mr Fooz..:

不,调用delete堆栈分配的变量是不安全的.你应该只调用delete创建的东西new.

对于每个malloc或者calloc,应该只有一个free.

每个new应该只有一个delete.

每个new[]应该只有一个delete[].

对于每个堆栈分配,应该没有明确的释放或删除.在适用的情况下,会自动调用析构函数.

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


"应该"是一个更好的词."必须"意味着如果不存在free/delete/delete [],则malloc/new/new []将失败,但事实并非如此.使用"正好一个"带有我认为你想要的含义.
在您的编辑中,我们可以用"必须"替换每个"应该".
谢谢!我的编译器没有错误,但如果它是合法的,我肯定是怀疑的.

2> Jeremy Ruten..:

好吧,我们来试试吧:

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

显然它根本不安全.


我知道这是一个陈旧的答案,但我不得不评论说,尝试某些东西可能不是证明它是安全的最佳方式; 如果它有效,那并不意味着操作是安全的或者行为是明确定义的,它只会证明它有效*一次*.(你可以用这种方式证明事情*不起作用*但反过来并不总是成立.)
@cdhowie这是一个不可思议的评论.尝试一些并发现它不安全*确实*证明它是不安全的.这就是答案所在.如果回答者没有找到他的例子来进行段错,他可能根本就没有发布它.在达到这个例子之前,你不知道他尝试过多少东西.
我想你错过了*my*point @itzJanuary
@jwg公平地说,我想我做到了.

3> Ferruccio..:

请记住,当您使用new(或malloc)分配内存块时,分配的实际内存块将大于您的要求.内存块还将包含一些簿记信息,以便在释放块时,可以轻松地将其放回到空闲池中,并可能与相邻的空闲块合并.

当你试图释放你没有从新收到的任何记忆时,那个簿记信息就不会存在,但是系统会像现在这样行事,结果将是不可预测的(通常很糟糕).



4> dasblinkenli..:

是的,它是未定义的行为:传递给delete任何不是来自newUB的东西:

C++标准,第3.7.3.2.3节:提供给标准库中提供的一个释放函数的第一个参数的值可以是null指针值; 如果是这样,并且如果解除分配函数是标准库中提供的函数,则对释放函数的调用不起作用.否则,operator delete(void*)标准库中提供的值应为先前调用operator new(std::size_t)operator new(std::size_t, const std::nothrow_t&)在标准库中调用返回的值之一.

未定义行为的后果是未定义的."没有任何事情发生"与其他任何事情一样有效.但是,它通常"没有立即发生":解除分配无效的内存块可能会在后续调用分配器时产生严重后果.



5> Sambatyon..:

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

    在堆栈变量上调用delete似乎没有做任何事情.没有错误抛出,但删除后我可以毫无问题地访问变量.

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


你的答案实际上与这个问题有关.总是有太多的福音传播程序员谴责任何人出于自己的纯粹好奇心(我在这里的原因)问一个问题是什么标准应该出现在语言的意外角落里面.

6> 小智..:

没人知道会发生什么.这会调用未定义的行为,所以任何事情都可能发生.不要这样做.


@ddriver如果你需要这个,你的设计是严重缺陷的.反思它,这应该不是问题.
@ddriver:你从哪里得到QObject的东西?在Qt API文档中,在[QObject :: ~QObject()](http://qt-project.org/doc/qt-4.8/qobject.html#dtor.QObject)中,它清楚地说:_警告:所有孩子对象被删除.如果这些对象中的任何一个在堆栈或全局上,则程序迟早会崩溃._
推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有