为什么下面的代码没有崩溃,虽然我删除了对象?

War*_*ior 7 c++

class object
{
  public:
    void check()
    {
      std::cout<<"I am doing ok..."<<std::endl;
    }
};

int main()
{
  object *p = new object;
  p->check();
  delete p;
  p->check();
  delete p;
  p->check();
}
Run Code Online (Sandbox Code Playgroud)

编辑:大师,我很困惑的许多声明"它可能崩溃或可能没有"..为什么没有标准说,这是我们如何处理使用'删除操作符'删除的内存块..?有什么投入?

Sre*_*kel 10

因为在编译器完成之后它实际上是什么样子,是这样的:

object::check( object* this )
{
     // do stuff without using this
}

int main()
{        
     object *p = new object;
     object::check( p );
     delete p;
     object::check( p );
     delete p;
     object::check( p );
 }
Run Code Online (Sandbox Code Playgroud)

由于你没有触及"这个",你实际上并没有访问任何不良内存.

虽然,删除p两次应该可以导致崩溃:

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.2


laa*_*lto 7

因为该函数没有对对象的成员数据或this指针做任何事情.

这就像调用函数一样

void check(object *self)
{
  std::cout<<"I am doing ok..."<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

使用无效指针作为self参数.

虽然有双重删除,但在某些环境中可能会崩溃.

  • 是的,因为方法不是对象的一部分.方法是课程的一部分.尝试回顾OO原则.属性和行为.属性与对象关联,行为是类级别.所有对象的行为方式都相同.在幕后,所有对象都存储在一个函数表中,对函数的调用只是指向函数起始地址的指针跳转.有关详细信息,请查看此问题的答案. (2认同)

tsc*_*ble 7

删除仅释放内存并使其可用于堆.

在调用delete之后,指针的值是未定义的,因此可能不会崩溃.

我用来减少编程错误的编程技巧是在删除之后将指针设置为NULL.通过这种方式,您知道在删除指针后不会意外地使用指针.

  • 一个真实的陈述,但完全不适用于这个"问题". (2认同)

ral*_*nja 5

只要您从不访问类实例的状态,就可以使用nil指针执行相同的操作:

class object
{
  public:
    void check()
    {
      std::cout<<"I am doing ok..."<<std::endl;
    }
};

int main()
{
  object *p = 0;
  p->check();
}
Run Code Online (Sandbox Code Playgroud)


haa*_*vee 5

它甚至比那更有趣.这编译和运行很好:

#include <iostream>
using namespace std;
class object {
    public:
      void check() {
          cout << "I am doing ok..." << endl;
      }
};

int main() {
   object *p = (object*)0;
   p->check();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

在shell上:

$ g++ -o t t.cc
$ ./t
I am doing ok...
$

:)你实际上不必有一个对象来调用这个方法!欢呼声,h