C/C++内存管理

 1.C/C++中内存分布

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

 

238ca78e486544bb9e22384c198d5ed3.jpeg

 

//text.cpp
#include<iostream>
using namespace std;


int globalvar = 1;
//全局变量放在静态区
static int staticvar = 1;
//全局静态变量也放在静态区
void Text()
{
	static int staticvar = 1;
	//局部静态也放在静态区
	int localvar = 1;
	//局部变量,放在栈里
	int num[10] = { 1,2,3,4,5 };
	//数组放在栈内
	char char2[] = "abcd";
	//将" a b c d \0" 拷贝给数组char2, 数组放在栈
	*char2;
	//数组名代表整个数值,对其解引用得到首元素,数值仍在栈内
	const char* pchar3 = "abcd";
	//const修饰,pchar3指向的内容不可修改,局部变量仍然在栈上开辟空间
	*pchar3;
	//数组名代表整个数值,对其解引用得到首元素,而"a b c d \0"是临时变量,所以存放在常量区

	//变量的开辟在栈内
	int* ptr1 = (int*)malloc(sizeof(int) * 4);
	int* ptr2 = (int*)calloc(4,sizeof(int));
	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);

//动态开辟的内存在堆区,解引用得到首元素地址
	*ptr1;
	*ptr2;
	*ptr3;
	free(ptr1);
	free(ptr3);	
}


int main()
{


	return 0;
}

2.C语言中动态内存管理方式:malloc/calloc/realloc/free

http://t.csdnimg.cn/sruBN

3.C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此·C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理

 

	//text.cpp
#include<iostream>
using namespace std;



class A {
public:
	A(int a=0,int b=0)
{}
~A()
{}

};


int main()
{
	//动态申请一个int 类型的空间
	int* p1 = new int;
	//释放p1指向的空间
	delete p1;

	//动态申请10个int 类型的空间
	int* p2 = new int[10];
	//释放p2指向的空间
	delete[] p2;

	//动态申请+初始化
	int* p3 = new int(5);
	int* p4 = new int[10]{ 1,2,3,4,5 };

	delete p3;
	delete[] p4;
	//动态申请一个A类并默认构造初始化
	A* p5 = new A;
	//动态申请一个A类并带参构造初始化
	A* p6 = new A(1,0);
	A* p7 = new A(1);
	//动态申请一个A类数值并默认构造初始化
	A* p8 = new A[3]{ {},{},{} };
	//动态申请一个A类数值并带参构造初始化
	A* p9 = new A[3]{ {1,2},{3,4},{5,6} }; 
	A* p10 = new A[3]{ {1,2},{3,4},{} };
	A* p11 = new A[3]{ {1,2} };

	//先默认构造出三个对象,然后拷贝构造给动态开辟的数组
	A aa1(1, 2);
	A aa2(3, 4);
	A aa3(5, 6);
	A* p12 = new A[3]{ aa1,aa2,aa3 };
	A* p13 = new A[3]{ A(1,2),A(3,4),A(5,6) };
	return 0;
}

 new和delete会调用构造和析构

class A {
public:
	A(int a=0,int b=0)
{
		cout << "A(int a=0,int b=0)" << endl;
	}
~A()
{
	cout << "~A()" << endl;
}
int _a1 = 1;
int _a2 = 2;
};

int main()
{
	A* ptr1 = new A;
	delete ptr1;
	return 0;
}

 8cbda35eff6d43c59c9ad2deb32c78ad.png

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间用new[]和delete[]。一定要匹配起来使用,否则容易内存泄漏,如下

class A {
public:
	A(int a=0,int b=0)
{}
~A()
{}
int _a1 = 1;
int _a2 = 2;
};
class B {

private:
	int _b1 = 1;
	int _b2 = 2;

};
int main()
{//不报错
	int* p1 = new int[10];// ->malloc
	delete p1;            //->free

	B* p2 = new B[10];
	delete p2;

	//报错
	A* p3 = new A[10];
	delete p3;
	return 0;
}

自定义类型在创建时会额外开一个整形放在开头记录对象个数,而编译器看到B没有写析构函数而优化了所以没有开,这个整形开辟是方便delete[]释放的,B释放的ptr2的指向的空间,释放完全,而A还有一个整型大小没有释放,所以内存泄漏报错

978c176f3c3844318383c9858933567a.jpeg

4.operator new 与 operator delete函数

  • new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete 是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间
  • operator new 实际也通过malloc来申请空间的,如果malloc
  • 申请成功直接返回地址,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete最终是通过free来释放空间的

 

5.new 和 delete的实现原理


内置类型

如果申请的是内置类型的空间,new和malloc,delete和free基本相似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续的空间,而且new在申请空间失败时会抛异常,malloc会返回空

自定义类型

  • new的原理
  1. 调用operator new函数申请空间
  2. 在申请空间上执行构造函数,完成对象的构造
  • delete的原理
  1. 在空间上执行析构函数,完成对象中资源的清理工作
  2. 调用operator delete函数释放对象的空间
  • new T[N]的原理
  1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成对N个对象空间的申请
  2. 在申请的空间上执行N次构造函数
  • deleted[]的原理
  1. 在释放的对象空间上执行N此析构函数,完成对N个对象中资源的清理
  2. 调用operator delete[]释放空间,实际在operator delete[] 中调用operator delete来释放空间

 

     

 

相关推荐

  1. 内存管理

    2024-07-19 21:06:01       34 阅读
  2. C/C++——内存管理

    2024-07-19 21:06:01       60 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-19 21:06:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-19 21:06:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-19 21:06:01       58 阅读
  4. Python语言-面向对象

    2024-07-19 21:06:01       69 阅读

热门阅读

  1. vue中v-if和v-for

    2024-07-19 21:06:01       20 阅读
  2. 计算机视觉10 总结

    2024-07-19 21:06:01       16 阅读
  3. 什么是RPC

    2024-07-19 21:06:01       19 阅读
  4. 《Exploring Orthogonality in Open World Object Detection》

    2024-07-19 21:06:01       19 阅读
  5. 电商B2B2C模式详细介绍

    2024-07-19 21:06:01       19 阅读
  6. ubuntu 22.04安装Eigen

    2024-07-19 21:06:01       20 阅读
  7. 【手撕数据结构】把玩顺序表

    2024-07-19 21:06:01       21 阅读
  8. 链表(Linked List)-Python实现-使用类和使用函数

    2024-07-19 21:06:01       24 阅读
  9. HTML语义化

    2024-07-19 21:06:01       22 阅读