C/C++ 内存管理

1. C/C++内存分布


globalVal 是全局变量,在静态区 C

staticGlobalVar 是全局的静态变量,在静态区 C

staticVar 是局部的静态变量,在静态区 C

localVar 是局部变量,在栈,具体来说是在栈帧里面 A

num1 是一个局部数组,在栈 A

char2 是一个局部数组,在栈 A,它里面的数据abcd,是从常量区里面拷贝来的,'abcd'都是在栈,所以char2 是'a',在栈 A
pchar3 是一个指针,在栈 A,它指向常量区里面的内容'abcd',所以
pchar3是在常量区,D

ptr1 是一个指针,在栈 A,它指向在堆上开辟的一段空间,所以*ptr1是在堆上,B

填空题:

2. C语言中动态内存管理方式

cpp 复制代码
void Test ()
{
	int* p1 = (int*) malloc(sizeof(int));
	free(p1);
	// 1.malloc/calloc/realloc的区别是什么?
	//calloc = malloc + memset 申请空间+初始化
	//realloc 是重新调整空间,异地扩容 or 原地扩容
	int* p2 = (int*)calloc(4, sizeof (int));
	int* p3 = (int*)realloc(p2, sizeof(int)*10);
	// 这里需要free(p2)吗? 不需要 因为realloc返回新的空间首地址
	free(p3 );
}

3. C++中动态内存管理

3.1 基础语法:

cpp 复制代码
    // malloc没有办法很好支持动态申请的自定义对象初始化
	A* p1 = (A*)malloc(sizeof(A));
	//p1->_a = 0;
	//p1->A(1);

	// 自定义类型,开空间+调用构造函数初始化
	A* p2 = new A;
	A* p3 = new A(3);

	// 自定义类型,调用析构函数+释放空间
	delete p2;
	delete p3;

	A* p4 = new A[10];
	delete[] p4;

	A aa1(1);
	A aa2(2);
	A* p5 = new A[10]{aa1, aa2};
	delete[] p5;


	A* p6 = new A[10]{ A(1), A(2)};
	delete[] p6;

	A* p7 = new A[10]{ 1, 2 };
	delete[] p7;

3.2

func函数中new了一个stack类,先开空间,再调用构造函数,构造函数里面又会new一个数组,new了两次;返回stack类的指针,delete时,先调用析构函数 ,将stack类里面的数组成员delete,然后再将stack类delete;

如果主函数没有delete,那么ptr是内置的指针类型,不会去调用析构函数,数组的空间泄露,到程序结束,stack类开辟的空间被释放。

4. operator new与operator delete函数

operator new 的用法和malloc 是一样的,区别是malloc失败之后会返回0,而operator new 会抛出异常,如果有try 和 catch语句的话,就执行。如果没有try 和 catch语句的话,程序崩溃。

其实,operator new 是为了之后的new做铺垫。

operator new 是对malloc的封装

同理 operator delete 是对 free 的封装

异常操作语法大致如下:

cpp 复制代码
void func()
{
	char* p1 = new char[0x7fffffff]; //内存会开辟失败
	cout << "hello world" << endl;
}

int main()
{
	try
	{
		func();
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}

4.1

改成cout << p1 << endl;就不行了。除了char* 的其他的指针类型,cout打印的时候,打印的就是指针,也就是地址。而char* 类型的指针不一样,编译器会当他是字符串,打印的是它的内容,所以应该强转:(void*)p1 or (int*)p1。

5. new和delete的实现原理

===================================


结论:一定要匹配使用!!!

6. 定位new表达式(placement-new)

和内存池搭配用

有时候不直接从堆上申请空间,因为效率速度不高,从内存池上取空间,这时候不会调用构造函数,就需要定位new 来显式调用构造函数

7. 常见面试题

相关推荐
旖旎夜光5 分钟前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
扶尔魔ocy1 小时前
【QT入门到晋级】用开源的自定义控件开发
c++·qt·自定义控件
akinggw2 小时前
libsherpacore - 基于 sherpa-onnx 的 C++ 语音交互静态库
c++·交互·语音识别
xiaoye-duck2 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
東隅已逝,桑榆非晚3 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
eggwyw4 小时前
C++相交链表和反转链表详解
开发语言·c++
杜 硕4 小时前
从零开始的C++生活——第六讲——02
c++·算法·生活
小超人诞生日记4 小时前
C++ STL 反向迭代器:从源码框架到适配器实现
c++·算法
青少儿编程课堂4 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园成语接龙大挑战解析
c++·python·算法·bfs·信息学竞赛
小贾要学习4 小时前
【C++后端开发项目】Reactor 模型 / C++ 仿写 muduo HTTP 服务器:让底层网络库真正跑起网页
linux·服务器·c++·http·网络编程·muduo·reactor模型