【问题标题】:Checking value of deleted object检查已删除对象的值
【发布时间】:2015-06-22 15:28:09
【问题描述】:

我问了一个问题:

Detecting if an object is still active or it has been destroyed

考虑到我不能使用库,C++ 中没有好的开箱即用解决方案。因此,通过分析已删除对象所在的内存来检查对象是否已被销毁是一种不好的做法,请考虑以下代码:

#include <stdio.h>

class Foo {
 public:
    static unsigned int foo_id_gen;    // unique id generator
    unsigned int id;
    int a;
    Foo() {
      ++foo_id_gen;
      if (foo_id_gen == 0) {           // Handle rollover of unique ID
        ++foo_id_gen;
      }
      id = foo_id_gen;                 // Set unique ID
    }
    ~Foo() {
      id = 0;                          // Set unique ID to Zero
    }
};

unsigned int Foo::foo_id_gen = 0;

class FooPtr {
 public:
    Foo* ptr;
    unsigned int id;
    explicit FooPtr(Foo* foo_obj_ptr) {
      ptr = foo_obj_ptr;
      id = foo_obj_ptr->id;
    }
    bool valid() {
      return (ptr->id == id);
    }
};

int main() {
  Foo* A = new Foo;
  FooPtr APtrOjb(A);
  printf("Is valid?: %s\n", APtrOjb.valid() ? "Valid" : "Not Valid");
  delete A;
  printf("Is valid?: %s\n", APtrOjb.valid() ? "Valid" : "Not Valid");
}

当类 Foo 的对象被创建时,它得到一个永远不会为零的唯一 ID,当对象被删除时,析构函数将唯一 ID 设置为零。然后 FooPtr 类型的对象可以通过检查 id 是否匹配来检查 Foo 类的对象是否仍然处于活动状态。

注意:我意识到检查 id 并不能 100% 获得结果,因为当内存被分配用于其他目的时,匹配发生的可能性很小。那么让我们假设id验证方法可以加强到被授予者100%的结果,这是一个可行的解决方案吗?

有人提出这个问题类似于C++ delete - It deletes my objects but I can still access the data?,但他的问题是关于删除数据,而我的问题是关于检测对象是否被删除。

【问题讨论】:

  • 这不是解决办法。您正在尝试重新发明shared_ptr/weak_ptr。当与make_shared 一起使用时,内存占用与您的课程非常相似,但不会污染您的课程。它也被证明是有效的,它是合法的代码。为什么不能使用shared_ptrstdboost 实现?
  • @stefan,谢谢你让我远离糟糕的设计......

标签: c++


【解决方案1】:

这很糟糕,在一般情况下访问已删除的对象,就好像它们没有被删除一样会崩溃。不能保证内存仍然在进程内映射,并且可能导致虚拟内存页面错误。

内存也很可能会被同一类的不同实例重新使用,因此它看起来是有效的,但实际上并非如此。

通常,这种设计会导致难以分析的错误。

您的测试程序的范围也非常有限。它不能说明大型程序的行为。

【讨论】:

  • 这就是为什么每个实例的 ID 都会改变,所以第 2 段不是 NA,但第 1 段是需要考虑的,但我没有操作系统要处理(没有页面错误),所以这是严格的 C++ 问题。
  • 除非您实际上是自己编写操作系统(在这种情况下,您可以做任何您想做的事情,因为您负责系统上的所有内存),那么您确实有一个操作系统要处理与,即使它是一个简单的操作系统。
猜你喜欢
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 2011-04-18
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多