背景:new是C++里的操作符,可以被重载来按照自己希望的方式来分配内存,malloc是C里的函数
区别(一):new自动分配内存,无需计算大小,malloc需要sizeof来取大小
class Test
{
public:
int arg1;
int arg2;
char* arg3;
};
int main(int argc, char* argv[])
{
auto test1 = new Test;
auto test2 = malloc(sizeof(Test));
return 0;
}
区别(二)new自动识别返回的对象的指针类型,malloc返回void*类型,需要强制转换
区别(三)分配失败的处理不同
C中没有异常机制,所以malloc分配失败时会返回NULL,早期的C++中new分配内存失败时也是返回NULL,而如今gcc的编译器对于C++标准支持比较好,所以当new分配内存失败时会抛出异常。
区别(四)分配的空间不同
new从自由存储区(free store)上分配内存,也可以在已经分配了内存的区间取内存给别的使用,如下图:
malloc则是调用brk在堆上分配虚拟内存,如果超过128K(不同系统和实现中可能会有所差异)则是通过mmap在文件映射区分配虚拟内存
区别(五)删除空间时的步骤不同
delete会去先调用对象的析构函数,然后再去释放空间
虽然delete可以用于释放void*指针指向的内存,但这是一种危险的操作,不推荐使用。delete操作符的工作方式是它需要知道要释放的对象的类型,这样它才能正确地调用对象的析构函数(如果有),然后再进行内存清理。
free空间释放分为brk调用后的空间释放和mmap调用后的空间释放,如果是brk申请的空间则会回收到内存池里,如果是mmap则是立刻释放内存
题外话
题外话(一)free怎么知道要释放多少内存
但是如果malloc出来的空间不进行强制转换的话是void*类型,free清理的时候又是怎么知道要释放的空间的大小呢,
其实当使用malloc函数分配内存时,它返回的是一块连续的内存空间的起始地址。这块内存空间的头部(在用户层面通常不可见)包含了一些用于内存管理的信息(16字节)。
在CSAPP中有讲解
题外话(二)malloc是怎么分配内存的
当要分配的内存小于128k时,会优先在malloc维护的内存池里分配内存,这样做是为了避免直接去调用系统调用 brk,因为brk会涉及到用户态到内核态的一个切换代价
内存池还能避免缺页异常
然后才是brk直接分配堆上内存。brk的性能很好,因为它只需要简单地移动程序中断位置,不需要像mmap那样建立复杂的内存映射关系。
CSAPP里有对brk和sbrk的解释
当需要分配较大的内存块时,mmap系统调用更合适。这是因为mmap可以直接从操作系统的内存管理模块(文件映射区)获取一大块连续的虚拟内存地址空间,并且可以通过合适的页表设置将其映射到物理内存。对于大内存分配,mmap的内存布局更加灵活,能够更好地利用系统的内存资源。