new / malloc / calloc / realloc的区别

本文介绍了C++中四种用于动态内存管理的方法:new/malloc/calloc/realloc,并详细对比了它们之间的区别。包括如何使用这些方法分配和释放内存,以及它们在自定义类型中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

new / malloc / calloc / realloc都能在堆上动态开辟空间,那么他们之间有什么区别呢??

下面先对上述的操作符或者函数逐个介绍


目录

一、malloc函数

二、calloc函数

三、realloc函数

四、new操作符

1、给内置类型开辟空间

2、给自定义类型开辟空间

五、new/delete的底层调用

六、malloc底层实现

七、new和malloc 的区别


一、malloc函数

 malloc 按字节大小申请空间,但不会初始化

函数声明:void* malloc (size_t size);

参数:申请空间所占字节数( = 申请的元素个数num * 每个元素所占的字节数)

返回值:申请成功时,返回空间地址;申请失败时,返回NULL

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num = 10;
    int* pData = (int*)malloc(num * sizeof(int));
    if(pData == NULL)
    {
        printf("申请空间失败");    
    }
}

二、calloc函数

 calloc 按字节大小申请空间,同时会初始化为 0

函数声明: void* calloc (size_t num, size_t size);

第一个参数:申请开辟 num 个元素的空间大小

第二个参数:每个元素所占字节数

返回值:申请成功时,返回空间地址;申请失败时,返回NULL

#include <stdio.h>

int main()
{
    int num = 10;
    int* pData = (int*)calloc(num , sizeof(int));
    if(pData == NULL)
    {
        printf("申请空间失败");    
    }
}

 

三、realloc函数

realloc 在已经申请好内存块的基础上,重新分配,但不会初始化

(1)若之前没有申请,那么直接分配,和malloc用法一致

(2)若已经申请过了,就有两种情况

       - 新分配的内存块比原来大

        在原来的基础上新增 或者 在其他地方开辟一块空间,将数据拷贝进去,释 放原本的空间

       - 新分配的内存块比原来小,在原本的基础上削减

函数声明:void* realloc (void* ptr, size_t size);

第一个参数:已经申请过的空间地址(若未申请,则填NULL)

第二个参数:申请空间所占字节数( = 申请的元素个数num * 每个元素所占的字节数)

返回值:申请成功时,返回空间地址;申请失败时,返回NULL

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int num = 10;
    int* pData = (int*)realloc(num, sizeof(int));
    if (pData == NULL)
    {
        printf("申请空间失败");
    }
}

四、new操作符

new 按照元素个数申请空间,自动检测元素类型,计算所需字节数

中括号 [ ]:申请多个元素的空间

小括号 ( ):申请一个元素的空间,给这个空间初始化

无括号:申请一个元素的空间,但不初始化

1、给内置类型开辟空间

#include <stdio.h>
#include <stdlib.h>

int main()
{
    //动态申请10个int类型的空间
    int* pData1 = new int[10];    
    //不需要时,通过delete把空间释放
    delete[] pData1;    

    //动态申请一个int类型的空间,不初始化
    int* pData2 = new int;
    delete pData2;  
    
    //动态申请一个int类型的空间,初始化为10
    int* pData3 = new int(10);
    delete pData3;  
    
}

注意:

释放多个元素的空间时,要使用delete[ ],加了[ ],编译器会自动计算申请了几个元素

释放一个元素的空间时,直接使用delete 即可

2、给自定义类型开辟空间

使用new给自定义类型开辟空间的方式 和前面一样,但不一样的是,使用new给自定义类型开辟空间时,会调用构造函数;释放空间,会调用析构函数

#include <stdio.h>
#include <stdlib.h>

class A
{
public:
    A()
    {
        printf("A的默认构造函数被调用了\n");
    }
private:
    int _a;
};

int main()
{
    A* pa = new A;
    //A* pa = new A[10];

    delete pa;
}

 申请一个对象,相当于创建了一次对象,会调用一次构造函数

 申请10个对象,相当于创建了10次对象,会调用10次构造函数

五、new/delete的底层调用

operator new 和operator delete是系统提供的全局函数

-》new在底层调用operator new全局函数来申请空间,operator new再去调用malloc

        申请成功则直接返回

        申请失败会抛出异常,而不是像malloc一样返回null

-》delete在底层通过operator delete全局函数来释放空间

六、malloc底层实现

malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲快。采用隐式链表将所有空闲块连接,每一个空闲块记录了一个未分配的、连续的内存地址。

  • 当开辟的空间小于 128K 时,调用 brk 函数
  • 当开辟的空间大于 128K 时,调用 mmap 函数

 

七、new和malloc 的区别

1、new是操作符,malloc是函数(定义的角度)

2、new的参数是申请的元素个数,malloc的参数是 申请空间所占字节数(参数的角度)

3、malloc的返回值是 void*,必须要强转,new不需要(返回类型)

4、给自定义类型开辟空间时,new会调用构造函数,malloc不会(特殊情况,自定义类型)

5、new发生错误是抛异常,malloc返回null

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值