C++内存管理基础之new & delete

C++14--内存管理new delete int main()//new/delete和malloc/free最大区别是new/delete对于[自定义类型]除了开空间//还会调用构造函数和析构函数free(p1);delete p2;//内置类型是几乎是一样的free(p3);delete p4;free(p5);return 0; 阅读详情

内存管理的基础是要知道怎么获得以及释放内存,如你所知,在C/C++中就是调用new和delete操作。
1. 分清operator new和new operator
    全局函数operator new通常这样声明:
void * operator new(size_t size);
返回值类型是void*,表示其返回的是一个未经处理(raw)的指针,指向未初始化的内存。参数size_t确定分配多少内存。你能增加额外的参数重载函数operator new,但是第一个参数类型必须是size_t。头文件<new>中有一个很好的重载的例子,那就是placement new,它看上去象这样:
void * operator new(size_t, void *location)
{
  return location;
}
这初看上去有些陌生,但它却是new操作符的一种常见重载方法,使用一个额外的变量buffer,当new操作符隐含调用operator new函数时,把这个变量传递给它。被调用的operator new函数除了持有强制的参数size_t外,还必须接受void*指针参数,指向构造对象占用的内存空间。未被使用的(但是强制的)参数size_t没有参数名字,以防止编译器警告说它未被使用。在使用placement new的情况下,调用者已经获得了指向内存的指针,因为调用者知道对象应该放在哪里。placement new需要做的就是返回传递给它的指针。
    我们更经常使用的new是new操作符(new operator),而非操作符new(operator new),如当你使用new操作符构建一个对象的时候,实际上做了两件事情,一是调用operator new函数获取内存,二是调用对象的构造函数,如:
string *ps = new string("Hello, world!");
它完成与下面代码相似的功能:
void *memory = operator new(sizeof(string));         // 为String对象得到未经处理的内存
call string::string("Hello, world!") on *memory;     // 调用构造函数初始化内存中的对象
string *ps = static_cast<string*>(memory);           // ps指针指向新的对象

    注意第二步中构造函数的调用只能由编译器完成,用户是不允许这样操作的,也就是说如果你想建立一个堆对象就必须用new操作符,不能直接像上面一样调用构造函数来初始化堆对象。
    new操作符(new operator)是编译器内置的,其行为被语言固定下来,不受用户控制。但是它们所调用的内存分配函数也就是操作符new(operator new)则可以根据需要进行重载。试着回顾new操作符(new operator)与操作符new(operator new)的关系,如果你想在堆上建立一个对象,应该用new操作符。它既分配内存又为对象调用构造函数。如果你仅仅想分配内存,就应该调用operator new函数,它不会调用构造函数。如果你想定制自己独有的内存分配过程,你应该重载全局的operator new函数,然后使用new操作符,new操作符会调用你定制的operator new。如果你想在一块已经获得指针的内存里建立一个对象,应该使用placement new。
    最后需要记住的一点是,delete和new一样具有以上的特性,只是需要注意的一点是delte操作符中是首先调用对象的析构函数,然后再调用operator delete函数的。

2. 针对数组的new[]和delete[]操作   
    建立数组时new操作符(new[])的行为与单个对象建立(new)有少许不同:
第一是内存不再调用用operator new函数进行分配,代替以operator new[]函数(常称作array new)。它与operator new一样能被重载,允许定制数组的内存分配,就象定制单个对象内存分配一样。
第二个不同是new[]操作时调用构造函数的数量。对于new[]而言,在数组里的每一个对象的构造函数都必须被调用。
    delete[]操作符的语义基本上和new[]相同,他们的实现类似这样:
void * operator new[](size_t size)
{
 cout << "new size of array in new[](): " << size << endl;
 int *g =(int *) malloc(sizeof(size)); 
 return g;
}

void operator delete[](void* p)
{
 cout << "delete address of array pointer in delete[](): " << p << endl; 
 free(p); 
}

3. operator new和delete函数的实现
    operator new实际上总是以标准的C malloc()完成,虽然并没有规定非得这么做不可。同样,operator delete也总是以标准得C free()来实现,不考虑异常处理的话他们类似下面的样子:
extern void* operator new( size_t size )
{
    if( size == 0 )
        size = 1;       // 这里保证像 new T[0] 这样得语句也是可行的
   
    void *last_alloc;
    while( !(last_alloc = malloc( size )) )
    {
        if( _new_handler )
            ( *_new_handler )();
        else
            return 0;
    }
    return last_alloc;
}

extern void operator delete( void *ptr )
{
    if(ptr)  // 从这里可以看出,删除一个空指针是安全的
        free( (char*)ptr );

OpenClaw 完整部署教程 版本:OpenClaw 2026.2.13更新日期:2026-02-26适用系统:Linux (Ubuntu/Debian/CentOS) 阅读详情

相关推荐

pta——特立独行的幸福

这是我认为比较复杂的一道题了,比较迷茫的点在于不知道要算各位平方和几次到不了1,才算他不是幸福数。突破口在于如果如果不是回到1也会有一些数字重复出现,只要重复出现的数字不是1,那就不是幸福数

m0_65620244的博客 4018

重载newdelete方法实现C++内存安全

C++使用new关键字创建的对象,被分配到堆内存空间,然后得到对象地址,当程序复杂庞大时容易发生访问地址bug或内存泄露bug。为了避免内存泄露并在调试程序时找到内存泄露的bug,可以重载newdelete函数,确保程序的内存安全。     newdelete关键字都可以作为operator来重载重载new函数规定一个参数size_t表示需要在堆空间上分配的内存大小,可以认为等于size

zjc156m的专栏 1299

【MATLAB2016a】模糊自适应PID双闭环直流调速系统(带负载)

【MATLAB2016a】模糊自适应PID双闭环直流调速系统(带负载),使用步骤请看B站视频https://www.bilibili.com/video/BV1Zu411e7qW?spm_id_from=333.999.0.0&amp;vd_source=7c338f7ca9e256485c1a0c569850c46c

从零开始学C++重载 operator new 和 operator delete 实现一个简单内存泄漏跟踪器

先来说下实现思路:可以实现一个Trace类,调用 operator new 的时候就将指向分配内存的指针、当前文件、当前行等信息添加进Trace 成员map容器内,在调用operator delete 的时候删除这些信息。定义一个全局Trace 对象,当程序结束,对象析构时判断成员map 是否还有信息,如果有则打印出来,表示已经发生内存泄漏,从输出可以看出是哪一个文件哪一行分配了内存但没有释放掉。

Meditation 4356

智能指针基础std::auto_ptr与newdelete重载学习笔记

在C/C++中我们malloc/new申请的内存都要自行释放,除非程序结束,否则会造成内存泄漏,这么久以来分配释放已经成为一个习惯,但是有时候还是会有疏漏,忘记释放。而C++中有这么一类东西,它可以替我们释放不再使用且未手动释放的内存,这种所谓的东西就叫做智能指针。而智能指针有多种(std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::sc

Apollon_krj的博客 1820

重载newdelete

new 表达式的工作机理如下: 第一步:调用一个名为operator new(或者operator new[])的标准库函数 该函数分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象(或者对象数组) 第二步:编译器运行相应的构造函数以构造这些对象,并为其传入初始值。 第三步:对象被分配了空间并构造完成,返回一个指向该对象的指针 delete 表达式的工作机制如下: 第一步:对对象调用

pzh的博客 1254

C++ 重写重定义的区别记录

又忘了。 #include &lt;iostream&gt; using namespace std; class Car { public: virtual void Drive() = 0; //纯虚函数 void Drive1() {cout &lt;&lt; "Drive_CAr" &lt;&lt; endl;}; }; class Benz :public Car { public: virtual void Drive() { cout &lt;&lt;

more_HH 310

C++干货基地】深度理解C++中的高效内存管理方式 new & delete

终于到了我们都喜欢的内存管理部分了,兄弟还没有对象那就来 new 一个对象吧。哈哈哈这是来自广大程序员的调侃,也说明了 new 是可以去申请对象空间的关键字今天我们就来深度研究一下吧!

鸽芷咕的博客 1万+

浅谈 C++ 中的 new/deletenew[]/delete[]

C++ 中,你也许经常使用 newdelete 来动态申请和释放内存,但你可曾想过以下问题呢? newdelete 是函数吗?new [] 和 delete [] 又是什么?什么时候用它们?你知道 operator new 和 operator delete 吗?为什么 new [] 出来的数组有时可以用 delete 释放有时又不行?… 如果你对这些问题都有疑问的话,

海风林影 16万+

C++干货铺】内存管理newdelete

C&C++内存管理!!!malloc/realloc/calloc/free!!!new/delete!!!

qq_55119554的博客 2657

C++内存管理 —— newdelete

本文主要对 C 语言中的动态开辟内存的方式进行回顾,并对 C++ 中新增的 newdelete 操作进行详细讲解。

2401_87820834的博客 2188

关于C++中常用的对DEBUG_NEW、THIS_FILE重定义的说明

//============================================================================= #ifdef _DEBUG // 判断是否定义_DEBUG #define new DEBUG_NEW // 定义调试new宏,取代new关键字 #undef THIS_FILE // 取消THIS_FILE的定义 static

xuhuan_wh的专栏 3276

C++重定义

【注意】重定义的源头 Coordinate.h文件: class Coordinate{ public: Coordinate(int x,int y); ~Coordinate(); void setX(int x); int getX(); void setY(int y); int getY(); public: int m_iX; int m_iY; };

sunSHINEEzy的博客 828

彻底搞清C++中的重载、重定义、重写

1、重载首先说重载,它最简单,C++中的重载和java中的差不多,都是在一个类中,方法名相同而参数不同的几个方法,但是不能靠返回类型来判断。例如:class AA { public: void print() { cout << "父类" << endl; } void print(int x ) { cout << "父类:"

文哥 9252

C/C++动态内存管理

关于malloc/free,new/delete的具体操作过程。

fmflb的博客 223
上一篇: C/C++中的内存对齐
下一篇: 感悟生活之-工作
sharpdew
博客等级 码龄23年 76粉丝 35原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值