浅谈malloc、calloc和realloc

malloc、calloc和realloc是动态内存开辟的函数,在了解他们之前先想一下为什么要动态内存开辟?
我们以前开辟内存时是通过下面这种方式:

int val = 10; //在栈上开辟四个字节
char arr[10] = {0};//在栈上开辟10个字节的连续空间

这种方式是在栈上开辟内存,有以下特点:
1.开辟的空间是固定的;
2.数组在声明的时候,必须指定数组的长度,它所需要的内存在编译时分配。

可是有时我们需要的空间大小在程序运行时才能知道,所以在编译时开辟空间的方式就不能满足。所以这时候只能试试动态内存开辟。

C语言提供了三个动态内存开辟的函数:malloc、calloc和realloc

malloc

函数原型:

void* malloc(size_t size);

用来向内存申请一块连续可用的空间,空间开辟成功则返回指向这块空间的指针,失败返回NULL指针,所以必须对返回值做检查,判断内存是否开辟成功。

特点:开辟的空间没有初始化,如果这块内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配过,那么就有可能出错,所以使用这块空间前先将其初始化。

calloc

函数原型:

void* calloc(size_t num,size_t size);

函数的功能是为num个大小为size的元素开辟一块空间,并把每个空间初始化为0.

如果是为字符类型或整数类型的元素分配内存,那么这些元素将被初始化为0,如果为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针,如果是浮点型元素,则这些元素会被初始化为浮点型的0。

realloc

函数原型:

void* realloc(void* ptr,size_t size);

该函数可以调整动态开辟的内存大小。
ptr是调整后的内存地址,size是调整后的新大小,返回值为调整后的内存的起始地址。

realloc在调整内存空间时存在两种情况:
1.原有空间之后有足够大的空间:
扩展内存直接在原有内存之后直接追加,原有空间数据不发生变化。
2.原来空间之后没有足够大的空间:
扩展方式:在堆空间另找一个合适大小的连续空间,然后将原来数据拷贝到新空间,这时函数返回一个新的内存地址。

注意:所有动态开辟的内存都要手动释放,用free函数,否则会内存泄漏。

验证malloc和calloc:
#include <stdio.h>
#include<stdlib.h>
int main()
{
    int* ptr = NULL;
    ptr = (int*)malloc(10 * sizeof(int));
    if (ptr != NULL)
    {
        int i = 0;
        for (; i < 10; i++)
        {
            *(ptr + i) = 0;
        }
    }

    free(ptr);
    ptr = NULL;
    return 0;
}

使用malloc结果:
这里写图片描述
调用该函数后分配了4*10个字节的大小,但是没有进行初始化。
这里写图片描述
使用循环将这些空间初始化为0.

调用calloc函数呢?

#include <stdio.h>
#include<stdlib.h>
int main()
{
    int* ptr = NULL;
    ptr = calloc(10, sizeof(int));
    if (ptr != NULL)
    {

    }
    free(ptr);
    ptr = NULL;
    return 0;
}

结果:
这里写图片描述
从上图可以看见,calloc函数自动将其分配的空间初始化为0了。

三者区别:

1.三者的声明都在 stdlib.h头文件中。
2.calloc可以初始化所分配的内存空间,而其他两个不能。
3.realloc可以对动态开辟的内存空间进行扩大或缩小,无论是扩大还是缩小,原有的内存中的内容将保持不变,当然,对于缩小,则被缩小的那一部分的内容将会丢失,realloc并不保持调整后的内存空间和原来的内存空间保持同一内存地址,realloc返回的指针很可能指向新的地址。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值