一、接口简介
> /* 函数原型:
> 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