V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  C++

对 delete 和 shared_ptr 的行为 这么理解正确吗?

  •  1
     
  •   amiwrong123 · 2022-01-11 23:43:43 +08:00 · 1381 次点击
    这是一个创建于 807 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include <iostream>
    #include <memory>
    using namespace std;
    
    class Line
    {
    public:
        Line(double len, int a);   // 这是构造函数声明
        ~Line();  // 这是析构函数声明
    
    private:
        double length;
        double* nums;
    };
    
    Line::Line(double len, int a)
    {
        length = len;
        nums = new double[a];
        cout << "Object is being created" << endl;
    }
    Line::~Line(void)
    {
        delete [] nums;
        cout << "Object is being deleted" << endl;
    }
    
    int main() {
        Line* line = new Line(1.0, 2);
        delete line;
    
        {
            shared_ptr<Line> aaa = make_shared<Line>(1.0, 2);
        }
    
    	return 0;
    }
    

    我对这个程序的理解如下:

    delete line;将做出以下动作:

    • 先调用 Line 的析构函数,再释放 line 指向的内存(使用全局的::operator delete )。
      • double 占 8 字节,double*占 4 字节,但考虑内存对齐,所以 line 占的内存为 16 个字节。
    • 在 Line 的析构函数中,执行 delete [] nums;
      • 先调用 double[]的析构函数(话说有这种玩意吗??)
      • 再释放 double[]的内存(使用全局的::operator delete [])

    shared_ptr<Line> aaa局部变量做的事情和delete line;一样。

    各位大佬看下我的理解对吗

    5 条回复    2022-01-12 10:01:52 +08:00
    wevsty
        1
    wevsty  
       2022-01-12 00:05:26 +08:00
    没有 double[] 的析构函数这种玩意。
    对于内置类型 delete 和 delete [] 的行为没有区别,都是直接释放内存。
    如果是 class 类型,delete [] 会调用数组里每个元素的析构函数,然后再释放内存。
    wevsty
        2
    wevsty  
       2022-01-12 00:07:22 +08:00
    另外 double* 不一定是占用 4 字节,比如 X64 下面就是 8 字节。
    wevsty
        3
    wevsty  
       2022-01-12 00:16:51 +08:00
    查了一下,说错了,更正一下:
    operator delete[] 是有的,并且可以重载。
    mingl0280
        4
    mingl0280  
       2022-01-12 09:25:52 +08:00
    前面那个我是被整怕了,可以用宏打出来看一看。
    后面那个嘛……首先,double 是 POD ,所以它的 delete[]会遍历所有数组项然后释放内存,该操作因为是 POD 所以没有析构——肯定是走的全局的那个 operator delete 。
    如果你的"double"并不是一个 POD 的东西,那么这个东西会调用这个东西内的 operator delete[],这个有。
    amiwrong123
        5
    amiwrong123  
    OP
       2022-01-12 10:01:52 +08:00 via Android
    @mingl0280
    delete[]会遍历所有数组项然后释放内存

    感觉这次遍历好像做了一次无用功呢,也没有析构函数可以调
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2810 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:39 · PVG 22:39 · LAX 07:39 · JFK 10:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.