【问题标题】:is delete this + memmove(this,new A(),sizeof(A)) safe and is it a bad idea?delete this + memmove(this,new A(),sizeof(A)) 安全吗?这是个坏主意吗?
【发布时间】:2015-07-08 08:02:53
【问题描述】:

我在c++中搜索了一些关于delete this的帖子,知道delete this通常是一个坏主意,因为delete this通常意味着管理不善:new和delete的数量不匹配,也可能有一些指针在外面类仍然指向这个。

但我搜索的帖子主要是关于删除原始对象,并没有讨论将原始对象替换为新对象的情况。

有时我想重新创建对象,因为我希望对象回到初始状态,通过使用 delete this+memmove(this,new A(),sizeof(A)) 来“realloc”对象,如下所示:

class A{
public:
    int value;
    void test(){
        delete this;
        memmove(this,new A(),sizeof(A));
    }
};

安全吗?还是有任何未定义的行为?

即使它有效,它是一种糟糕的编码风格吗?

【问题讨论】:

  • 提示:执行delete this;this 指向什么?而new A()分配的内存又会怎样?
  • A a; a.test(); 嗯...是的。为了:它不安全,它调用 UB(不仅仅是我展示的情况)。
  • @amuse 到目前为止,您已经在 SO 上提出了 41 个问题,其中 37 个问题至少收到了一个答案,但您还没有将一个标记为已接受。如果某个答案最有助于解决您的问题,您可以通过单击旁边的勾号将其标记为已接受。

标签: c++ memory-management coding-style


【解决方案1】:

这段代码大量存在于 UndefinedBehaviour-land 中。 delete this 不仅仅调用析构函数——它还释放内存。 memmove 因此复制到未分配的内存中。

此外,它还存在内存泄漏,因为从new A() 返回的指针会立即被遗忘。

我相信你打算这样做:

void test()
{
  this->~A();
  new (this) A();
}

这会调用this上的析构函数,然后调用this指向的空间中的默认构造函数。

不过,真正的问题是为什么要这样做。这是相当复杂的低级管理。在我看来,最好给类一个适当的赋值运算符并这样做:

void test()
{
  *this = A();
}

请记住,代码的作用越容易理解,代码通常就越好。

【讨论】:

    【解决方案2】:

    delete 这个释放内存。所以 memmove 写入一个悬空指针,这是未定义的行为。

    我不知道您要做什么,但是您是否尝试过移动 c++11 中引入的构造函数?

    【讨论】:

      【解决方案3】:

      您可以调用delete this - 在某些引用计数实现中使用的自毁机制以这种方式工作但是您可能根本不会再引用this,因为结果未定义。

      如果您想将同一个对象恢复到初始状态,那么您不能提供私有的 cleanup()init() 方法来完成这项工作吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-16
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-16
        • 1970-01-01
        • 2013-06-30
        相关资源
        最近更新 更多