删除后访问指针

时间:2019-05-06 16:02:40

标签: c++

我有一个如下的代码段。我为我的Something类创建了一些动态内存分配,然后将其删除。 代码会打印出我期望的错误数据,但是为什么->show不会崩溃? 在什么情况下/ ->show会导致崩溃? 是否可以用其他对象覆盖i,ii,iii的相同存储位置?

我试图了解为什么在delete之后释放了要写入的内存位置的信息之后,仍然还有关于->show的信息!

#include <iostream>
#include <vector>

class Something
{
public:

  Something(int i) : i(i)
  {
    std::cout << "+" << i << std::endl;
  }

  ~Something()
  {
    std::cout << "~" << i << std::endl;
  }

  void show()
  {
    std::cout << i << std::endl;
  }
private:
  int i;

};

int main()
{
  std::vector<Something *> somethings;

  Something *i = new Something(1);
  Something *ii = new Something(2);
  Something *iii = new Something(3);

  somethings.push_back(i);
  somethings.push_back(ii);
  somethings.push_back(iii);

  delete i;
  delete ii;
  delete iii;

  std::vector<Something *>::iterator n;
  for(n = somethings.begin(); n != somethings.end(); ++n)
  {
    (*n)->show(); // In what case this line would crash? 
  }

  return 0;
}

2 个答案:

答案 0 :(得分:3)

请记住,指针存储一个整数存储地址。在调用delete时,将释放动态内存,但指针仍将存储内存地址。如果我们使指针为空,则程序将崩溃。

看到这个问题:What happens to the pointer itself after delete?

答案 1 :(得分:2)

  

代码会输出我期望的错误数据,但是why ->show不会崩溃?

为什么您同时期望数据错误,但还会崩溃?

通过无效指针间接进行的行为是不确定的。期望数据是正确的,或者期望数据是错误的,或者期望它应该崩溃,也不能期望它不应该崩溃是不合理的。

  

在什么情况下->show会导致崩溃?

在任何情况下,C ++语言都不会指定要崩溃的程序。崩溃是C ++特定实现的详细信息。

例如,如果您尝试写入标记为只读的内存区域或尝试访问未映射的内存区域,则Linux系统通常会由于“段错误”而导致进程崩溃。

在标准C ++中没有直接的方法来创建内存映射:语言实现负责为您创建的对象映射内存。

以下是在特定系统上demonstrably crashes的程序示例:

int main() {
    int* i = nullptr;
    *i = 42;
}

但是C ++不保证它会崩溃。

  

是否可以用其他对象覆盖i,ii,iii的相同存储位置?

该行为是不确定的。就语言而言,一切皆有可能。