为什么在使用赋值时不调用析构函数的堆栈变量?

b

这段愚蠢的代码已经花了我2个小时,我不知道为什么第一个元素的析构函数(大小为7的析构函数)没有被调用?分配的内存会new uint16_t[7]怎样?

#include <iostream>

using namespace std;

struct Node
{
    Node(uint16_t n) : p(new uint16_t[n]) {
        cout<<"Constructed with size= "<<n<<", memory addr: "<<(p)<<endl;
        for(uint16_t i=0; i<n; i++) p[i] = n;
    }

    ~Node() {
        cout<<"Destructor for p[0] = "<< *p <<" with memory addr: "<<p<<endl;
        delete[] p;
    }

    uint16_t *p;
};

int main()
{
    {
        Node nd1(7);
        {
            nd1 = Node(3);
            cout << "1st place holder" << endl;
        }
        cout << "2nd place holder" << endl;
    }

    return 0;
}

输出是

Constructed with size= 7, memory addr: 0x158cc20                                                                                                                                   
Constructed with size= 3, memory addr: 0x158cc40                                                                                                                                   
Destructor for p[0] = 3 with memory addr: 0x158cc40                                                                                                                                
1st place holder                                                                                                                                                                   
2nd place holder                                                                                                                                                                   
Destructor for p[0] = 0 with memory addr: 0x158cc40                                                                                                                                
*** Error in `./a.out': double free or corruption (fasttop): 0x000000000158cc40 ***                                                                                                
Aborted (core dumped) 
纪尧姆·拉西科特(Guillaume Racicot)

这段代码:nd1 = Node(3);不是您所期望的。

不会取代nd1Node(3)和杀老nd1

它的作用是创建一个新的临时节点实例Node(3),并将每个成员的值复制到中nd1因此,临时和nd1包含指向同一地址的指针。那时,您泄漏了nd1在程序开始时分配的内存,因为没有指针引用它,但是您没有删除它。

当临时对象死亡时,nd1指向死内存。nd1运行它在第二析构函数},它删除同一指针再次因此你的错误。


要解决此问题,您必须实现所谓的5规则或零规则。

最简单的是零规则。只需使用unique_ptr,销毁就会按预期进行:

struct Node
{
    Node(uint16_t n) : p(std::make_unique<uint16_t[]>(n)) {
        cout<<"Constructed with size= "<<n<<", memory addr: "<<(p)<<endl;
        for(uint16_t i=0; i<n; i++) p[i] = n;
    }

    std::unique_ptr<uint16_t[]> p;
};

int main()
{
    {
        Node nd1(7);
        {
            nd1 = Node(3); // assignement destroys the old buffer
            cout << "1st place holder" << endl;
        }
        cout << "2nd place holder" << endl;
    }

    return 0;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么emplace_back调用析构函数?

来自分类Dev

为什么在全局变量的析构函数中调用thread.join失败

来自分类Dev

删除void指针时不调用析构函数

来自分类Dev

当对象绑定到成员函数时,为什么std :: function会调用析构函数?

来自分类Dev

为什么析构函数被调用三次?

来自分类Dev

为什么在std :: move之后需要析构函数调用?

来自分类Dev

为什么在构造时调用C ++类的析构函数?

来自分类Dev

为什么我的类析构函数立即被调用?

来自分类Dev

为什么调用从对象移出的析构函数?

来自分类Dev

为什么在插入析构函数时总是得到“在抛出...实例后终止调用”?

来自分类Dev

为什么析构函数被调用两次?

来自分类Dev

为什么析构函数比构造函数调用得更多?

来自分类Dev

为什么析构函数调用两次表单?

来自分类Dev

当我单击控制台上的关闭按钮时,为什么不调用析构函数?

来自分类Dev

C ++为什么在堆栈中构造完对象后立即调用析构函数?

来自分类Dev

为什么std :: vector :: emplace调用析构函数而不调用任何拷贝构造函数?

来自分类Dev

为什么析构函数会不断地自我调用(导致堆栈溢出)?

来自分类Dev

为什么在Friend函数中调用析构函数

来自分类Dev

为什么在使用unique_ptr时没有调用析构函数?

来自分类Dev

为什么不调用继承类的析构函数?

来自分类Dev

为什么代码两次调用析构函数?

来自分类Dev

当对象绑定到成员函数时,为什么std :: function会调用析构函数?

来自分类Dev

为什么在构造时调用C ++类的析构函数?

来自分类Dev

为什么在调用luaL_error时未调用C ++对象析构函数?

来自分类Dev

为什么我的类析构函数立即被调用?

来自分类Dev

为什么在复制分配期间调用析构函数?

来自分类Dev

当将对象作为参数传递时,为什么要调用析构函数但不调用构造函数?

来自分类Dev

C ++为什么在堆栈中构造完对象后立即调用析构函数?

来自分类Dev

为什么在声明指向对象的指针时不调用析构函数

Related 相关文章

  1. 1

    为什么emplace_back调用析构函数?

  2. 2

    为什么在全局变量的析构函数中调用thread.join失败

  3. 3

    删除void指针时不调用析构函数

  4. 4

    当对象绑定到成员函数时,为什么std :: function会调用析构函数?

  5. 5

    为什么析构函数被调用三次?

  6. 6

    为什么在std :: move之后需要析构函数调用?

  7. 7

    为什么在构造时调用C ++类的析构函数?

  8. 8

    为什么我的类析构函数立即被调用?

  9. 9

    为什么调用从对象移出的析构函数?

  10. 10

    为什么在插入析构函数时总是得到“在抛出...实例后终止调用”?

  11. 11

    为什么析构函数被调用两次?

  12. 12

    为什么析构函数比构造函数调用得更多?

  13. 13

    为什么析构函数调用两次表单?

  14. 14

    当我单击控制台上的关闭按钮时,为什么不调用析构函数?

  15. 15

    C ++为什么在堆栈中构造完对象后立即调用析构函数?

  16. 16

    为什么std :: vector :: emplace调用析构函数而不调用任何拷贝构造函数?

  17. 17

    为什么析构函数会不断地自我调用(导致堆栈溢出)?

  18. 18

    为什么在Friend函数中调用析构函数

  19. 19

    为什么在使用unique_ptr时没有调用析构函数?

  20. 20

    为什么不调用继承类的析构函数?

  21. 21

    为什么代码两次调用析构函数?

  22. 22

    当对象绑定到成员函数时,为什么std :: function会调用析构函数?

  23. 23

    为什么在构造时调用C ++类的析构函数?

  24. 24

    为什么在调用luaL_error时未调用C ++对象析构函数?

  25. 25

    为什么我的类析构函数立即被调用?

  26. 26

    为什么在复制分配期间调用析构函数?

  27. 27

    当将对象作为参数传递时,为什么要调用析构函数但不调用构造函数?

  28. 28

    C ++为什么在堆栈中构造完对象后立即调用析构函数?

  29. 29

    为什么在声明指向对象的指针时不调用析构函数

热门标签

归档