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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/YIMG/p/13363147.html