C++初阶 | [五] 内存管理

摘要:new and delete,定位new,(C++内存管理的方式),malloc/free和new/delete的区别,内存泄漏

关于内存: 

  1. 又叫堆栈——非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(目前只需了解一下)
  3. 用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段——存储全局数据和静态数据。
  5. 代码段——可执行的代码/只读常量。

1. new/delete——C++内存管理的方式

对于内置类型:

C++初阶 | [五] 内存管理_第1张图片

对于自定义类型:

C++初阶 | [五] 内存管理_第2张图片

使用示例: 

C++初阶 | [五] 内存管理_第3张图片


2. operator new与operator delete函数

(ps.operator new与operator delete函数不是运算符重载函数)

new 和 delete 是用户进行动态内存申请和释放的操作符,operator new 和 operator delete 是系统提供的全局函数,new 在底层调用 operator new全局函数来申请空间,delete 在底层通过 operator delete全局函数来释放空间。

  • operator new 实际也是通过malloc来申请空间
  • operator delete 最终是通过free来释放空间的 

1)开空间失败,抛异常

operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果该应对措施用户设置了,则继续申请,否则抛异常

int main()
{
	try
	{
		int* p = new int[0x7ffffffff];
		cout << "hello" << endl;//开空间失败该语句将不会被执行,直接跳转
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}

C++初阶 | [五] 内存管理_第4张图片

2)显式调用

Type* p = (Type*)operator new(sizeof(Type));//Type* p = new Type;

operator delete(p);//delete p;

3)new 和 delete 不匹配使用的问题

  • 对于内置类型:不匹配使用一般不会出什么问题
  • 对于自定义类型:一定要匹配使用!否则结果是未定义的!

C++初阶 | [五] 内存管理_第5张图片

warning:一定要匹配使用!new Type[n] → delete[];new → delete;malloc → free。 


3. 定位 new

定位new 表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。

class A
{
public:
	A(const int a)
		:_a(a)
	{

	}
private:
	int _a;
};


int main()
{
	A* pst = (A*)operator new(sizeof(A));//开空间但不初始化
	new(pst)A(0);//调用构造函数初始化

	pst->~A();//析构函数可以显式调用

	return 0;
}
  • 使用:new (place_address) type or new (place_address) type(initializer-list) 

内存池

(ps.构造函数不可以直接显式调用)

定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要通过使用new的定义表达式调用构造函数进行初始化

C++初阶 | [五] 内存管理_第6张图片


4. malloc/free和new/delete的区别

  • C++初阶 | [五] 内存管理_第7张图片①malloc/free是函数,new/delete是操作符
  • ②malloc的返回值为void*, 在使用时必须强转,new不需要
  • ③malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可
  • initializer:malloc申请的空间不会 初始化 ,new可以初始化
  • fail:malloc申请空间 失败 时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常
  • call:申请自定义类型对象时,malloc/free只会开辟空间,不会 调用 构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理

5. 内存泄漏

什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

普通程序内存泄漏问题不大,进程结束,会自动清理。但是,对于长期运行的程序影响很大,如操作系统、后台服务等等,内存泄漏会导致响应越来越慢,最终卡死。


END

你可能感兴趣的:(#,C++初阶,c++,c语言,开发语言)