C/C++动态内存管理方式

733 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

一、C语言中动态内存管理方式

💦 malloc/calloc/realloc和free

p2 calloc一块空间后,p3又realloc p2,要对p2 free吗 ❓

void Test ()
{
	int* p1 = (int*) malloc(sizeof(int));
	free(p1);
 	int* p2 = (int*)calloc(4, sizeof (int));
	int* p3 = (int*)realloc(p2, sizeof(int)*10);
	free(p3);
}

📝说明

这里涉及了 realloc 的开辟原理 在这里插入图片描述 所以对于上面程序的写法并不好: 在这里插入图片描述 【面试题】malloc/calloc/realloc的区别

malloc -> 开空间

calloc 等价于 malloc + memset(0) -> 开空间 + 初始化

realloc 单独使用时能实现 malloc 的效果 (不会初始化) -> 开空间 | 对 malloc/calloc 的空间扩容

二、C++内存管理方式

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

💦 new/delete操作内置类型

int main()
{
	//库函数
	int* p1 = (int*)malloc(sizeof(int));
	free(p1);
	
	//操作符/关键字
	int* p2 = new int;
	delete p2;

	return 0;
}

📝说明

malloc/free 和 new/delete 有什么区别 ❓

  • 如果动态申请的对象是内置类型,那么 malloc 和 free 没有区别
  • 如果动态申请的对象是自定义类型,那么 malloc 和 free 有区别

💦 new和delete操作自定义类型

class A
{
public:
	A(int a = 0/*int b = 0*/)
		:_a(a)
	{
		cout << "A()" << endl;	
	}
	~A()
	{
		cout << "~A()" << endl;	
	}
private:
	int _a;
};
int main()
{
	A* p3 = (A*)malloc(sizeof(A));
	free(p3);
	
	A* p4 = new A;
	//A* p4 = new A(10);
	//A* p4 = new A(10, 20);
	delete p4;
	
	//数组
	int* p5 = (int*)malloc(sizeof(int) * 10);
	free(p5);

	int* p6 = new int[10];
	delete[]p6;

	A* p7 = new A[10];//调用10次构造
	delete[]p7;//调用10次析构
	
	return 0;
}

📝说明

  • 对于内置类型 malloc/free 仅仅会开空间/释放空间
  • 对于自定义类型 new/delete 不仅仅会开空间/释放空间,还会调用构造函数和析构函数 —— 调用构造函数时还可以传参,且可以传多个参数

注意我们在 new A 类时不需要默认构造函数;但是在 new A[10] 时则需要默认构造函数

在 C++ 中建议尽量使用 new/delete,因为 malloc/free 能做到的,new/delete 也能做到;new/delete 能做到的,malloc/free 不一定能做到。 在这里插入图片描述

注意申请和释放单个元素的空间,使用 new 和 delete 操作符,申请和释放连续的空间,使用 new[] 和 delete[]

这种特性有什么用 ❓

struct ListNode
{
	int _val;
	ListNode* _next;
	ListNode(int val)
		: _val(val)
		, _next(nullptr)
	{}
};
int main()
{
	//C
	ListNode* n1 = (ListNode*)malloc(sizeof(ListNode));
	n1->_val = 1;
	n1->_next = nullptr;

	//C++
	ListNode* n2 = new ListNode(1);
	
	return 0;
}

牛角尖问题 ❓

int* p1 = (int*)malloc(sizeof(int) * 10);
free(p1);
delete p1;

int* p2 = new int;
delete p2;
free(p2);

int* p2 = new int[10];
delete[]p2;
delete[10]p2;
delete p2;//err
free p2;/err

📝说明

注意,一定要匹配使用:malloc ↔ free 、new ↔ delete、new 类型[] ↔ delete[]类型,否则可能会崩溃。