C++中如何自定义内存分配

在C++中使用new来进行内存分配和对象初始化。最常见的做法,当我们new一个对象时:

X *px = new X();

编译器会生成类似如下形式的代码:

void *memory = operator new(sizeof(X));// 得到未经处理的内存
call string::string()  on *memory;     // 调用初始化函数
X *px = static_cast<X*>(memory);       // px指针指向生成的对象

整个对象的生成过程可以细分为两个步骤:1)分配内存;2)在分配的内存上调用构造函数,完成初始化。这个过程的前后步骤是不可变的,但是其中的内存分配和构造函数,我们是可以自定义的。(跟设计模式中的模板模式比较像)。

首先区分几个概念:

new operator:new操作符,可以理解为关键字、操作原语,我们在代码中使用它来生成一个对象或者对象数组。

operator new:分配内存的函数,用户可以自己重定义。

placement new:可以认为是operator new的一个特例,它比operator new多一个内存地址作参数。


因此,自定义内存分配,有两种new操作:

new operator = operator new + constructor

new operator = placement new + constructor

注:两种方法new operator是不同的。后者要多一个参数。


一、operator new + constructor

这种情况下,只需要自己重新实现operator new即可。编译器对new operator进行扩展,调用用户自己定义的operator new进行内存分配,然后调用构造函数。

调用代码:

X *px = new X(); 


重写operator new

void * operator new(size_t size) {
...
  return 内存地址;
}

在嵌入式开发中,就会经常使用这样的方式:预先分配好固定的内存,用链表进行保存。operator new中只需要查找free list即可。这样做,一般有如下几个好处:

1)节省内存空间,可以省掉编译器分配内存时添加的附加信息(该信息保存给给delete释放内存时使用)。

2)省掉了搜索内存表的时间,加快了内存分配速度。并且避免了内存碎片产生。


二、placement new + constructor

与前面一种不同,有时我们有已经分配好的内存,只需要调用构造函数初始化即可,在这种情况下,我们会使用到placement new。它定义在<new>中,实现很简单:

inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
{ return __p; }

仅仅是将传入的内存地址返回而已(因为内存已经分配好了)。

调用代码:


char *buffer = new char[size];
X *px = new (buffer) X();

其中buffer为已经分配好的地址。当遇到上面的语句时,编译器会扩展语句,调用placement new,然后在内存上调用构造函数。


注意,这种情况下的内存释放,需要手工调用析构函数和释放内存操作:

px->~x();//调用析构函数
freeMemory(buffer);//伪代码,释放内存buffer


不能直接写:

delete px;


因为这样,编译器会扩展成:

px->~x();
operator delete(px);


其中,operator delete是没有定义的。


自定义内存分配时,需要注意的问题:
1. 如果重写 operator new,同样需要重写 operator delete,后者负责内存释放。
2. 如果重写 operator new,同样需要重写 operator new[]operator delete[],后者是针对数组。

X *px = new X[10];
delete[] px;



转载于:https://my.oschina.net/roxor/blog/603292

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值