malloc, calloc和realloc

一、接口简介

> /* 函数原型:
>      void *malloc(size_t size); 
>    功能:
>     在内存的动态存储区中分配长度为size的空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
>    返回值:
> malloc()和calloc()函数返回一个指向分配内存的指针,该指针适合于任何内置类型。发生错误时,这些函数返回NULL。
> 如果调用malloc()的size为0,或者调用calloc()的nmemb或size等于0,也可能返回NULL。
> */
 
> /* 函数原型:
>     void *calloc(size_t nmemb, size_t size); 
>    功能:
>     在内存的动态存储区中分配num个长度为size的空间,
>     函数返回一个指向分配起始地址的指针,并将分配的内存内容初始化为0;如果分配不成功,返回NULL。
> */
> /* 函数原型:
>     void *realloc(void *ptr, size_t size); 
>     功能:
>     realloc()函数将ptr指向的内存块的大小更改为size字节。从region的起始位置到新旧尺寸的最小值之间的内容都不会改变。
>     如果新大小大于旧大小,则新增的内存不会被初始化。如果ptr为NULL,那么对于所有size的值,调用等价于malloc(size);
>     如果size等于0,并且ptr不为NULL,则调用等价于free(ptr)。除非ptr为NULL,否则它一定是由之前调用的malloc()、calloc()或realloc()返回的。
>     如果指向的区域被移动了,则完成一个free(ptr)操作。 
>     返回值:
>     realloc()函数返回一个指向新分配内存的指针,该指针适合于任何内置类型,并且可能与ptr不同,如果请求失败,则返回NULL。
>     如果size等于0,则返回NULL或一个适合传递给free()的指针。如果realloc()失败,原始块不会受到影响;它没有被释放或移动。
> */

二、验证代码

#include <stdio.h>
#include <stdlib.h> //calloc
#include <string.h> //memcpy
#include <unistd.h> //sleep

#define MEM_COUNT 10

int main(int argc, char *argv[])
{
    char *realloc_ptr = NULL;
    char *new_realloc_ptr = NULL;
    char arr[] = "Hello World";

    for(int i=1; i<10; i++)
    {
        new_realloc_ptr = realloc(realloc_ptr, 64*1024*sizeof(char)*i);
        if(new_realloc_ptr != realloc_ptr)
        {
            printf("realloc_ptr[%d]: %p new_realloc_ptr:%p first char:%c\n", i, realloc_ptr, new_realloc_ptr, *new_realloc_ptr);
            realloc_ptr = new_realloc_ptr;
        }
        if((1==i) && (new_realloc_ptr!= NULL))
        {
            memcpy(new_realloc_ptr, arr, sizeof(arr));
        }        
    }

    int *malloc_ptr = malloc(MEM_COUNT*sizeof(int));
    if(NULL == malloc_ptr)
    {
        printf("Fail to malloc\n");
    }else
    {
        for(int i=0; i<MEM_COUNT; i++)
        {
            printf("malloc_ptr[%d](%d)\n", i, *malloc_ptr++);
        }
    }
    
    int *calloc_ptr = calloc(MEM_COUNT, sizeof(int));
    if(NULL == calloc_ptr)
    {
        printf("Fail to calloc\n");
    }
    else
    {
        for(int i=0; i<MEM_COUNT; i++)
        {
            printf("calloc_ptr[%d](%d)\n", i, *calloc_ptr++);
        }
    }

    return 0;
}

三、验证结果
(1)通过realloc()验证了:这三个函数通常是在堆内存中分配内存,当申请的内存超过MMAP_THRESHOLD字节(默认是128kB)时,glibc的三个内存分配函数会通过mmap()作为私有匿名映射来分配内存。
(2)malloc分配出来的内存没有初始化;
(3)calloc分配出来的内存有初始化为0;

四、Notes
Note1: malloc, calloc和realloc都是C语言提供的库函数,具体实现可以参考https://codebrowser.dev/glibc/glibc/

Note2: 快速了解使用的注意事项可以通过man malloc来查找用户手册。

Note3: 想进一步了解Linux 的虚拟内存,参考https://blog.csdn.net/wangcg123/article/details/79582118?spm=1035.2023.3001.6557&utm_medium=distribute.pc_relevant_bbs_down_v2.none-task-blog-2defaultOPENSEARCHRate-3-79582118-bbs-391042222.pc_relevant_bbs_down_v2_default&depth_1-utm_source=distribute.pc_relevant_bbs_down_v2.none-task-blog-2defaultOPENSEARCHRate-3-79582118-bbs-391042222.pc_relevant_bbs_down_v2_default

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值