C++中动态内存管理,用malloc/free模拟实现new/new[],delete/delete[]

     C++中动态内存管理的方式与C语言有所不同,在c++中通过new和delete运算符进行动态内存管理,通过深入剖析new/new[]和delete/delete[]来对c++的内存管理有更深入的了解

C语言

堆上使用malloc/calloc/realloc/free进行动态内存管理, malloc/calloc/realloc用来在堆上开辟空间,free将申请的空间释放掉

面试题:malloc/calloc/realloc三者之间的区别?

答:1)void *malloc(size_t size);size表示要分配的字节数,其中要检测空间是否开辟成功,开辟失            败时返回0

  2)作用:在内存中分配一个元素被初始化为0的数组。

   原型:void *calloc(size_t num,size_t size);num表示元素的个数,size表示每个元素的大小

   返回值:返回一个指向所分配空间的void指针。

  3)作用:重新分配内存块

   原型:void *realloc(void* memblock,size_t size);memblock指向原先分配的内存块,size表示新的内         存块的字节大小。

   返回值:返回一个指向重新分配(可能移动了)的内存块的大小。

注意堆上的内存需要用户自己来管理,动态malloc/calloc/realloc的空间,必须free掉,否则会造成内存泄漏

栈上开辟的内存由编译器自动维护,不需要用户显式释放

C++

下面看一个例子来显示new/new[]/delete/delete[]的使用:

void Test()
{
	int* p1 = new int;
	int* p2 = new int(3);
	int* p3 = new int[3];

	delete p1;
	delete p2;
	delete[] p3;
}

注意:new和delete,new[]和delete[]一定要匹配使用!

malloc/free和new/delete的区别和联系:

1)它们都是动态管理内存的入口 

2)malloc/free是C/C++标准库的函数,new/delete是C++操作符 

3)malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员) 

4)malloc/free需要手动计算类型大小且返回值会void*,new/delete 可自己计算类型的大小,返回对应类型的指针

深度剖析new/new[]/delete/delete[]

new:


delete:


new[]:


delete[]:


用malloc/free模拟实现new/delete/new[]/delete[]

class Test
{
public:
	Test()
	{
		_t = 0;
		cout << "Test()" << this << endl;
	}

	~Test()
	{
		cout << "`Test()" << this << endl;
	}
private:
	int _t;

};
//模拟实现new
void* New()
{
	//先开辟空间
	Test* pt = (Test*)malloc(sizeof(Test));
    if (NULL == pt)
    {
		assert(false);
		return NULL;
	}
	//在开辟的空间上执行构造函数
	new(pt) Test;
	return pt;
}

//模拟实现new[]
void* NewArray(size_t N)
{
	//先开辟空间,多开辟4个字节的空间用来存放对象的个数N
	int* p = (int*)malloc(sizeof(Test)*N + 4);
	if (NULL == p)
	{
		assert(false);
		return NULL;
	}
	*p = N;

	//在开辟的空间上执行构造函数
	Test* pt = (Test*)(p + 1);
	for (size_t i = 0; i < N; ++i)
	{
		new(pt + i) Test;
	}
	return pt;
}

//模拟实现delete
void Delete(Test* p)
{
	if (NULL == p)
		return;
	//先调用析构函数清理资源
	p->~Test();
	//再释放空间
	free(p);
}

//模拟实现delete[]
void DeleteArray(Test* pt)
{
	if (NULL == pt)
	{
		assert(false);
		return;
	}
	//取出对象的个数,再调用析构函数清理资源
	int *p = (int*)pt - 1;
	int N = *p;
	for (int i = N - 1; i >= 0; --i)
		pt[i].~Test();
	//释放空间
	free(p);
}


猜你喜欢

转载自blog.csdn.net/zimituanzi_/article/details/80868093