今天写作业的时候要求实现vector,很自然地用 malloc
,但是告知不能使用stdlib.h
,没有办法就只能使用new
了。于是忽然想到new
、malloc
都是在heap
上开辟动态空间,那么有什么异同呢?
malloc()
malloc只负责开辟一个指定大小的空间,类似的calloc
则使得在开辟空间的同时初始化为0。
malloc的特点在于将内存空间视为链表,在内存上找到足够长的初始空间返回给目标空间的开头地址,如果失败就会返回NULL
(因此使用malloc必须要检验返回指针)。
由于malloc开辟的空间在heap
上,这就使得可以在函数内定义的变量在函数被销毁会变量不会被同步销毁。因此释放heap的空间只能通过手动free()
。
malloc
在开辟新空间时往往会多开辟一些空间用于存储空间长度,前后空间指针的信息,由free
源码可见,实际上free是将heap
上的可用空间定义为指针传入的指针位置减去malloc所要求的大小--所以free本质上是定义了一个指针告诉OS:一个指针到另一个指针之间的空间是可用的free->is_available = 1;
。由此free
函数对传入的指针要求非常严格,必须是malloc空间的起始指针。
new()
intuitive的区别:
首先new
有个好处可以简单地进行初始化,即使用new时会调用该类型的默认构造函数。并且new
开辟的空间需要用delete
函数删除。
更重要的区别是:
new
函数调用的空间在C++被抽象为free store
(反向定义--new的空间才被视为free store,由OS特别管理)上。free store
一般都是在heap上,但是取决于new
自身的实现,也可以在static
区域。
new
有多种变体,如定位new--直接使用传入的地址而不考虑是否该地址为空可以使用new (address) int[10]
new
函数返回的指针类型与开辟空间的数据类型相符合,这就意味着不需要像malloc一样在cast后才能使用,在数据上更加安全。
new
如果分配失败,不会返回错误会直接丢出异常,如果想要确认需要使用catch
try
{
int *a = new int();
}
catch (bad_alloc)
{
...
}
summary:
特征 | new/delete | malloc/free |
---|---|---|
分配内存的位置 | 自由存储区 | 堆 |
|内存分配失败返回值| 完整类型指针 |void*
|内存分配失败返回值 |默认抛出异常 |返回NULL
分配内存的大小| 由编译器根据类型计算得出 |必须显式指定字节数
处理数组 |有处理数组的new版本new[] |需要用户计算数组的大小后进行内存分配
已分配内存的扩充| 无法直观地处理| 使用realloc简单完成
是否相互调用| 可以,看具体的operator new/delete实现| 不可调用new
分配内存时内存不足 |客户能够指定处理函数或重新制定分配器| 无法通过用户代码进行处理
函数重载| 允许| 不允许
构造函数与析构函数| 调用| 不调用