C/C++动态内存管理

1、malloc/free和new/delete之间关系和差异。

C通过malloc/free来管理动态内存,而C++通过new/delete管理动态内存。

malloc/free的使用方法与new/delete有所不同。

malloc/free:

int main()
{
        int *p=(int *)malloc(sizeof(int));
        
        free p;
        return 0;
}
malloc的函数原型为void *malloc(size_t size)

new/delete:

int main()
{
         int *p=new int;

         delete p;
         return 0;
}
new没有函数原型,因为new和delete都是C++中的关键字

总结它们之间的关联与区别:

(1)它们都是用来管理动态内存的。

(2)new/delete,malloc/free都要成对出现,否则会造成内存泄漏的问题。

(3)malloc函数在使用时需要指定开辟空间大小,而且因为malloc函数返回值是void*,所以需要强制转换。

而new则会自己及计算空间大小,返回对应类型指针。

(4)malloc/free只负责开辟空间释放空间,而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理

成员)。

(5)malloc/free是C的库函数,而new/delete是C++的关键字。

2、剖析new/delete、new[]/delete[]到底做了些什么事情。

在C++中,new/delete开辟对象空间,new[]/delete[]开辟对象数组空间。

new[]的方括号中是数组中对象的个数(N),使用new[]开辟空间时,不仅要开辟N个空间,还需要在这N个空间之前开辟4个字节的空间,

用来存放N,以此来告诉编译器要调用多少次构造函数,多少次析构函数。这4个字节非常重要。

int main()
{
           int *p1=new int;          //类型
           int *p2=new int(3);     //初始化
           int *p3=new int[3]; }    //数组个数
(1)new做了两件事:

a. 调用operator new分配空间。

b. 调用构造函数初始化对象。

(2)delete也做了两件事

a. 调用析构函数清理对象

b. 调用operator delete释放空间

(3)new[N]

a. 调用operator new分配空间。

b. 调用N次构造函数分别初始化每个对象。

(4)delete[]

a. 调用N次析构函数清理对象。(思考这里怎么N是怎么来的?)

b. 调用operator delete释放空间。

我们可以用图表示出来-------


3、实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

通过自己编写代码实现对于对象数组的开辟空间和释放空间,代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Array
{
public:
	Array(size_t size = 10)              //数组类的构造函数
		: _size(size)
		, _a(0)
	{
		cout << "Array(size_t size)" << endl;
		if (_size > 0)
		{
			_a = new int[size];
		}
	}
	~Array()                   //析构函数
	{
		cout << "~Array()" << endl;
		if (_a)
		{
			delete[] _a;
			_a = 0;
			_size = 0;
		}
	}
#define NEW_ARRAY(PTR,TYPE,N)\                                        //利用宏开展实现new[]
	do                                         \
	{                                          \
	PTR = (TYPE*)operator new(sizeof(TYPE)*N+4); \       //调用operator new函数开辟N个TYPE类型的空间,还要另外开辟4个字节空间
	(*(int*)PTR) = N;                          \         //在开辟的4个字节空间中存放N,即对象个数
	PTR = (TYPE*)((int*)PTR + 1);              \         //将PTR指针后移到对象空间
	for (size_t i = 0; i < N; ++i)             \         //对对象数组空间调用构造函数
	new(PTR + i)TYPE;                          \
	}while (false);                            \

#define DELETE_ARRAY(PTR,TYPE)\
	do{                                        \
	size_t N = *((int*)PTR - 1);               \          //在NEW_ARRAY中PTR指向对象数组,现在将4个字节处的值取出来赋给N
	for (size_t i = 0; i < N; ++i)             \          //调用析构函数释放空间
	    PTR[i].~TYPE();                        \
	PTR = (TYPE*)((char*)PTR - 4);         \           //开辟的空间还有4个字节未释放,将PTR前移,调用operator delete释放
	operator delete(PTR);                  \
	} while (false);
private:
	int*_a;
	size_t _size;
};

int main()
{
	Array*p1;
	NEW_ARRAY(p1, Array, 10);

	DELETE_ARRAY(p1, Array);
	system("pause");
	return 0;
}

运行结果如下,可以看出,调用了10次构造函数和10次析构函数


4、C语言中malloc,realloc,calloc的不同

在C语言中,malloc,realloc,calloc都是用来动态开辟内存空间的。
三个函数的申明分别是: 
void* realloc(void* ptr, unsigned newsize); 
void* malloc(unsigned size); 
void* calloc(size_t numElements, size_t sizeOfElement); 
都在stdlib.h函数库内

它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL 

malloc用于申请一段新的地址,参数size为需要内存空间的长度,如: 
char* p; 
p=(char*)malloc(20);

calloc与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,是申请连续字节空间,如: 
char* p; 
p=(char*)calloc(20,sizeof(char)); 
这个例子与上一个效果相同

realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度 
如: 
char* p; 
p=(char*)malloc(sizeof(char)*20); 
p=(char*)realloc(p,sizeof(char)*40);

C语言的标准内存分配函数:malloc,calloc,realloc,free等。 
malloc与calloc的区别为1块与n块的区别: 
malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。 
calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。 
realloc调用形式为(类型*)realloc(*ptr,size):将ptr内存大小增大到size。 


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值