• <七>深入理解new和delete的原理


    new ,delete 运算符

    int *p =new int;
    delete p;
    看一下汇编代码
    

    可以看到new 和delete 运算符其实也是 operator运算符重载函数的调用

    malloc和new
    malloc 按字节开辟内存 new在开辟内存的时候需要指定类型 new int[10]
    malloc 返回的是 void * 而 operator new 会帮助 转为 int *
    malloc只负责开辟空间, new 不仅仅有malloc的功能,可以进行数据的初始化 new int(20) new int100;
    malloc 开辟失败返回nullptr指针, new 开辟失败 是抛出 bad_alloc的异常

    try{
       int *p=new int;
       delete p;
    }catch(const bad_alloc & err){
        cerr<what()<

    free和 delete
    delete:调用析构函数 再 free()

    new -> operator new
    delete ->operator delete
    
    //先调用operator new 开辟内存空间,然后调用对象的构造函数(初始化)
    void * operator new(int size){
        void *p=malloc(size);
        if(p==nullptr){
           throw bad_alloc();
        }
        return p;
    }
    //delete p :调用p指向的对象的析构函数,再调用operator delete 释放内存空间
    void operator delete(void * p){
         free(p);
    }
    
    //针对数组用得new
    void * operator new[](int size){
        void *p=malloc(size);
        if(p==nullptr){
           throw bad_alloc();
        }
        return p;
    }
    
    //针对数组用得delete
    void operator delete[](void * p){
         free(p);
    }
    
    
    newdelete ; new[]  delete[] 能混用吗?
    
    class student{
    public:
    student(int age):page(new int(age)){
    
    }
    ~student(){
      delete  page;
    }
    
    private:
        int * page;
    }
    
    sutdent *ps=new student(20);
    delete ps;//student 会被析构
    delete [] ps;//执行报错
    
    sutdent *ps2=new student[20];
    delete []ps2;  //20个student 会被析构
    delete ps2;//执行报错
    
    

    从上图中可以看到 Test * p=new Test[5]; 编译器会申请  4+ 5 *4 =24个字节空间 前4个用于存储对象个数信息
    第5到第24个用于存储对象信息, 在delete [] p的时候,编译器发现了[],会去头4个字节中取出对象个数,然后再
    第5个自己到第20个字节按照每4个字节为一个对象进行 对象的析构函数的调用,最后 free(0x100);
    
    所以
    Test *p =new Test;
    delete [] p ;//运行时会报错, 除了析构p地址外,还会 free(p-4);这就有问题 因为 Test *p=new Test 只是一个对象
    时,不会产生前面4个字节的辅助信息
    
    Test *p =new Test[5];
    delete p; 只会析构p所指向地址的对象 0x104, free(0x104), 正确的是free(0x100) 所以运行报错
    
    自定义的类类型,有析构函数,为了调用正确的析构函数,那么开辟的对象数组的时候,会多开辟4个字节,记录对象的个数
    
  • 相关阅读:
    C语言基础(下)
    5.事务管理
    CodeTon Round 2 D. Magical Array 规律
    YOLOv5、v7改进之三十一:CrissCrossAttention注意力机制
    如何通过bat批处理实现快速生成文件目录,一键生成文件名和文件夹名目录
    Windows上安装pyenv,以及pyenv切换环境不生效的问题
    华南技术栈CNN+Bilstm+Attention
    PT_数字特征_矩协方差相关系数
    【10. 差分】
    AlphaControls控件TsRadioGroup的使用
  • 原文地址:https://www.cnblogs.com/erichome/p/16918031.html