zoukankan      html  css  js  c++  java
  • C++笔记——内存分配

    内存分配

    在学习C++控制内存分配部分主要区别以下几组函数:

    malloc/freeoperator new/deletenew operator/deleteplacement new/delete

    malloc/free与new/delete

    二者都可以从堆中申请和分配动态内存,并且二者都必须成对匹配使用,才可以正确完成内存的的申请和释放功能。

    区别:

    malloc/free是标准库中的函数,只能用来分配内部数据类型。

    new/delete是c++编译器自带的操作符,并且new内置了sizeof、类型转换和类型安全检查功能。对象在创建的同时需要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务分配给malloc/free。因此,需要new和delete运算符,new能完成动态内存分配和初始化工作,delete能完成清理与释放内存工作。

    operator new/delete与new operator/delete

    new operator/delete 即 new/delete,new用来完成对象的动态内存分配和初始化工作,delete用来完成清理与释放内存工作,operator new/operator delete是位于对应类中的函数,负责内存的分配和释放。

    new operator/delete

    new operator 在执行对象初始化时会有两个步骤:1、调用operator new为对象分配内存;2、调用对象的构造函数初始化内存;3、返回相应指针

    delete operator 执行时,也存在两个步骤:1、调用对象的析构函数销毁对象;2、调用operator delete释放内存;3、让给定指针为空

    new operator/delete 不可以被重载,但用户可以在类内部重载operator new函数operator delete函数

    operator new/ delete

    用户可以根据需求对operator new进行重载。重载时:

    1、返回类型必须声明为void*;

    2、第一个参数类型必须为表达要求分配空间的大小(字节被new调用),类型为size_t;

    3、可以带其它参数(new里面参数,传入operator new大小之后的参数列表)。

    operator delete 重载时:

    1、返回类型为void;

    2、参数为需要销毁的对象指针。

    class A
    {
        ...
        
        void* operator new (size_t size, ...){
            ... // 具体实现
            return ::operator new(size); //调用系统默认的operator new
        }
        
        void operator delete (void* p){
            ... // 具体实现
            return ::operator delete(p); /调用系统默认的operator delete
        }
    }
     

    placement new

    placement new 是 operator new 重载的一个版本,它不分配内存,可以将对象创建在已经被分配好的内存中,返回指向目标内存的一个指针,称为定位new。返回繁荣指针不能被删除,需要调用对象的析构函数来销毁,再delete原内存来释放内存。不存在与定位new表达式相匹配的delete表达式。

    placement new 使用步骤:

    1、提前分配内存;

    2、在已分配的内存上调用placement new创建对象;

    3、使用对象;

    4、使用完毕后调用对象的析构函数,销毁对象;

    5、可重复2、3、4步骤反复利用已分配的内存,不再使用内存时,使用delete释放。

    class A
    {
        ...
    }
    ​
    void main() {
        char *buff = new char[sizeof(A)]; // 1、分配内存
        A* p = new(buff) A; // 2、在已分配的内存上创建对象
        ... // 3、使用对象
        p->~A(); // 使用完毕后调用析构函数销毁对象,不释放内存
        ... // 可反复使用内存
        delete[] buff; // 释放内存
    }
    
    
    作者:YIMG
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    以此来励志吧!!!(选自:知乎)
    【P1303】苹果二叉树
    【P1813】8的倍数
    2016.9.4 の 測試
    后缀数组
    个中模板
    基数排序
    【NOIP2014D2T3】解方程
    【HAOI2006】【BZOJ1051】【p1233】最受欢迎的牛
    java安全性-引用-分层-解耦
  • 原文地址:https://www.cnblogs.com/YIMG/p/13363147.html
Copyright © 2011-2022 走看看