在 C++ 中将堆分配的类对象分配给堆栈分配的对象是否合法?

Kan*_*ony 0 c++ constructor destructor heap-memory stack-memory

在 C++ 中,我们可以通过取消引用来将类的堆分配对象分配给堆栈分配的对象。看起来没有问题,它可以按预期工作,即使析构函数也能正常工作,但是这样编写代码是好是坏?

#include <iostream>

class cls {
public:
    cls(int n) : pInt{new int{n}} {
        std::cout << "Constructor\n";
    }

    int *pInt;

    ~cls() { 
        std::cout << "Destructor\n";

        delete pInt; 
    }
};

int main() {
    cls *hObj = new cls{100};
    cls sObj = *hObj;
}
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 6

他们复制没问题,但请注意编译器生成的复制构造函数将执行复制。

这意味着,复制的是指针,而不是它指向的内容。这导致您有两个对象使用完全相同的pInt指针,指向完全相同的内存。而你只能delete记忆一次

这就是三、五和零规则的原因。


至于为什么这个程序似乎有效,那是因为你没有delete hObj。只有sObj析构函数会运行,所以在当前显示的代码中只有一个delete pInt.

如果您delete hObj在程序终止之前添加,那么两个析构函数将delete拥有相同的内存,并且您将有未定义的行为(并且很可能会崩溃)。

  • @LuisGo 因为 OP 代码错过了 `delete hObj;`。bug x bug = 看起来很好,但事实并非如此 (3认同)
  • @LouisGo 不,但是 OP 永远不会破坏 `hObj` 指向的对象。如果您执行“删除 hObj”,那么您将尝试“删除”内存两次。 (2认同)