C++内存管理
2021/5/5 7:27:32
本文主要是介绍C++内存管理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C++内存管理
- 内存分配层面
- Primitives
- 四原语实例
- new
- new expression
- array new
- placement new
- 改变内存分配机制
内存分配层面
学习内存管理主要是为了提高使用内存的效率和速度
一般而言,C++应用程序使用容器或使用new来申请内存,它们的底层实现都是malloc,很少直接与操作系统API打交道
Primitives
空间配置器allocator严格来说不算重载,应自由设计来搭配容器
四原语实例
operator new作用域是在全局的
使用空间配置器allocator需要指定分配空间大小,释放时也需要指定,容器适用此方法
new
new有两个动作,一个是分配内存,一个是调用构造函数
new expression
一个new表达式如下
Complex* pc = new Complex(1, 2);
编译器把这行语句转化为
Complex *pc; try{ void* mem = operator new( sizeof(Complex) ); //1, allocate pc = static_cast<Complex*>(mem); //2, cast pc->Complex::Complex(1, 2); //3, constructor } catch(std::bad_alloc){ // }
分配内存在第1行,operator new可重载,底层实现是malloc
第2行把指针转型
第3行调用构造函数,VC6可以通过,其他编译器会失败
要直接调用构造函数,可以使用placement new:
new( p)Complex(1, 2);
对应地,delete表达式:
delete pc;
编译器会转化为
pc->~Complex(); //先析构 operator delete(pc); //然后释放内存
可以直接调用析构函数
operator delete底层是free
array new
array new例子:
Complex* pca = new Complex[3]; //调用三次constructor //无法由参数给予初值 delete[] pca; //调用三次destructor
构造的pca布局如上图所示,其中cookie包含pca的长度,所有的C++编译器平台设计的malloc和free中的cookie都是如此。
当array new对应的是delete,如果对象没有destructor或destructor是trivial的,则不会发生内存泄漏,否则的话(对象的destructor有意义并且重要)会发生内存泄漏
比如:
int* pi = new int[10]; delete pi; //array new与delete对应,这样写可以,因为int没有destructor string* psa = new string[3]; delete psa; //错误,只会调用一次destructor,发生内存泄漏
并且根据对象的不同,其内存布局是不一样的
placement new
placement new允许将对象建构于已经分配的内存中,形式如下:
#include <new> char* buf = new char[sizeof(Complex) * 3]; Complex* pc = new(buf)Complex(1, 2); delete [] buf;
代码首先申请3个Complex大小的内存,用buf指针指向,然后在buf上创建对象
改变内存分配机制
我们已经知道new和malloc是不能重载的,所以可以通过重载operator new来改变内存分配机制
内存分配调用过程如下:
我们可以重载global functions,来改变内存分配机制,比如在类里重载
Foo::operator new(size_t); Foo::operator delete(void*);
改变内存分配机制主要是为了去除cookie
这篇关于C++内存管理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26MATLAB 中 A(7)=[];什么意思?-icode9专业技术文章分享
- 2024-11-26UniApp 中如何实现使用输入法时保持页面列表不动的效果?-icode9专业技术文章分享
- 2024-11-26在 UniApp 中怎么实现输入法弹出时禁止页面向上滚动?-icode9专业技术文章分享
- 2024-11-26WebSocket是什么,怎么使用?-icode9专业技术文章分享
- 2024-11-26页面有多个ref 要动态传入怎么实现?-icode9专业技术文章分享
- 2024-11-26在 UniApp 中实现一个底部输入框的常见方法有哪些?-icode9专业技术文章分享
- 2024-11-26RocketMQ入门指南:搭建与使用全流程详解
- 2024-11-26RocketMQ入门教程:轻松搭建与使用指南
- 2024-11-26手写RocketMQ:从入门到实践的简单教程
- 2024-11-25【机器学习(二)】分类和回归任务-决策树(Decision Tree,DT)算法-Sentosa_DSML社区版