c ++析构函数不会删除对象本身,是什么?

c++ destructor doesn't delete the object itself, what does?

首先,除非我误解了它,否则析构函数会释放对象内部变量占用的内存。在下面的示例中,它将删除 * str 指向的字符串。就这些了。

class StrPtr {
private:
    string * str;

public:
    StrPtr() : str(new string()) {} 
    
    ~StrPtr() { delete str; }
    void add(char c) { str->push_back(c); }
};

但是,这是我的困惑。如果析构函数不销毁对象本身。这是否意味着:

  1. for 循环后我有 10k StrPtr 对象。

  2. for 循环一结束,10k StrPtr 对象就会被删除,因为它们超出了范围。

  3. 每次 someF() 函数完成执行时,对象都会被删除,因为它超出了范围。因为这是创建它的地方。这是我目前的想法。

    void someF() {
        StrPtr s;
        s.add('a');
    }
    
    int main() {
        for (int i = 0; i < 10000; i++) {
            someF();
        }
    
    }

请参阅我的问题的选项 3。

没有内存泄漏,内存中永远不会超过一个 StrPtr 对象。

我想您只需要找出 'delete'、'deallocate' 和 'destroy' 之间的区别即可。可以帮助你的是观察

{
    A *a = new A;
    ...
    delete a;
}

实际上是这样工作的:

{
    A *a = static_cast<A *>(std::malloc(sizeof(A)); // allocate
    new (a) A(); // construct [placement new, something like a->A()]
    ...
    a->~A(); // destroy
    std::free(a); // deallocate
}

所以,'delete'表示'destroy',然后是'deallocate'。 分别是'create'表示'allocate',然后是'construct'.

在这个方案中,(std::malloc, std::free) 可以用任何其他分配策略代替——看看 https://en.cppreference.com/w/cpp/memory/allocator_traits 。 这同样适用于堆栈上的分配。

{
    A a;
    B b;
    ...
}

可能看起来像这样:

{
    // push %rbp
    // mov  %rsp, %rbp
    A *pa = <magic> // sub $sizeof(A), %rsp; pa <- %rsp
    B *pb = <magic> // sub $sizeof(B), %rsp; pb <- %rsp
    A &a = *pa;
    B &b = *pb;
    ...
    pb->~B();
    pa->~A();
    <deallocate everything>
    // mov  %rbp, %rsp
    // pop  %rbp
}

如果你想了解堆栈分配的魔力,你最好学习汇编的基础知识——你还将了解调用框架、调用约定和许多其他你通常需要记住的东西推导。