malloc,calloc,realloc三兄弟的那些事儿

本文详细介绍了C语言中malloc、calloc及realloc这三个内存管理函数的使用方法与注意事项,包括它们的功能区别、参数含义、如何避免野指针等问题。

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

概念:

  • malloc:用于申请一块指定大小的连续的内存区域,注意是在堆上开辟空间,如果开辟成功,返回该内存空间的首地址,如果开辟失败,返回空。
  • calloc:和malloc用法很像,都是为了在堆上开辟内存空间,不同的是,calloc函数会将开辟的内存空间初始化为0,而malloc开辟的空间内部大部分都是随机数值,不具备初始化的功能
  • realloc:用来调整已开辟内存空间的大小,调整时可扩大可缩小,扩大空间时,保留原有数据;缩小控件时,丢弃缩小那部分的数据,所以做缩小调整时要谨慎处理

用法:

三个函数引用的头文件都是< stdlib.h>

malloc:
  • 函数原型: void* malloc(size_t size);
  • 使用方法,举例:int p = (int)malloc(10*sizeof(int));//动态开辟10个整形数据单元
    1.调用malloc函数时,需要定义一个指针变量用来接收返回值,若内存开辟成功,返回该内存的首地址,如果开辟失败,则返回空。所以在调用完malloc函数时,通常需要判断下指针变量是否为空。
    2.原则上开辟后的空间地址返回类型为void*,但实际使用时我们常常会进行强转,使用会更加灵活
    3.不仅能开辟常用类型,也能开辟诸如结构体之类的组合类型,如:
    LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));

  • 注意事项(敲重点!!!):在使用完开辟的内存空间后,一定要记得用free()函数释放该空间,而且释放完空间后要将指向该空间的指针置空,不然会出现野指针的问题。所以最好将free()函数封装一下,在调用完free后就将指针置空。
    动态开辟的内存空间也是连续的,所以要防止越界访问

int* p = (int*)malloc(10*sizeof(int));
if(p==NULL)
{
printf("%s\n",strerror(errno));
exit(1);
}
//使用.......
free(p);
p=NULL;
calloc:
  • 函数原型:void* calloc(size_t n,size_t size);
    n : 成员数量
    size:每个成员的长度,以字节为单位
    意思就是在内存中开辟n个size大小的连续的空间
  • 使用方法:和malloc使用方法如出一辙,注意事项也一样,这里不做过多强调
int *p = (int*)calloc(10,10*sizeof(int));//意思是开辟了10个40个字节大小的连续空间
free(p);
p==NULL;
realloc:
  • 函数原型: void* realloc(void* mem_address,unsigned int newsize);
    mem_address: 要改变的内存空间的首地址,也是是指向该空间的首地址的指针
    newsize:新的内存空间的大小
  • 使用方法:将需要改变大小的内存空间的指针传进去,然后定义新空间的大小。大体使用方法和malloc,realloc一样,不过有额外需要注意的地方
    realloc在调整内存空间时存在两种情况:
    1:原有空间之后有足够的大的空间
    2:原有空间之后没有足够大的空间
    这里写图片描述
    这里写图片描述
  • 注意事项:
    1 .realloc也可以像malloc一样开辟新的空间,需要将mem_address传空值进去。空间开辟成功,返回新空间的地址,开辟失败,则返回NULL,说明剩余内存空间不够,原有的内存空间不变,所以在用指针接收realloc返回值时,最好使用新的指针,原有指针不要变动。
    2.如果将新空间的大小设置为0,则释放原有空间,并返回NULL
    3.如果新开辟的空间是上述第二种情况,则原有空间会被系统自动释放,无须担心
### C语言动态内存分配函数对比 在C语言中,`malloc`、`calloc` 和 `realloc` 是用于动态内存分配的个重要函数。它们的功能和使用场景各有不同,以下是它们的详细对比。 #### 1. `malloc` `malloc` 函数用于分配一块指定大小的内存,并返回指向该内存块的指针。分配的内存未初始化,其内容是不确定的值[^3]。 ```c void* malloc (size_t size); ``` - **参数**:`size` 表示需要分配的内存大小(以字节为单位)。 - **返回值**:成功时返回一个指向分配内存块的指针,类型为 `void*`;如果分配失败,则返回 `NULL`。 - **特点**: - 分配的内存未初始化,内容可能是随机值。 - 如果分配大小为零,行为取决于具体的库实现[^3]。 #### 2. `calloc` `calloc` 函数用于分配一块指定大小的内存,并将该内存初始化为零。它通常用于分配数组类型的内存[^1]。 ```c void* calloc (size_t num, size_t size); ``` - **参数**:`num` 表示元素的数量,`size` 表示每个元素的大小(以字节为单位)。 - **返回值**:成功时返回一个指向分配内存块的指针,类型为 `void*`;如果分配失败,则返回 `NULL`。 - **特点**: - 分配的内存会被初始化为零。 - 实际分配的内存大小为 `num * size`,因此适合用于分配数组[^3]。 #### 3. `realloc` `realloc` 函数用于调整之前分配的内存块的大小。它可以增大或缩小内存块的大小[^4]。 ```c void* realloc (void* ptr, size_t size); ``` - **参数**:`ptr` 是之前通过 `malloc` 或 `calloc` 分配的内存块的指针,`size` 是新的内存大小(以字节为单位)。 - **返回值**:成功时返回一个指向重新分配内存块的指针,类型为 `void*`;如果分配失败,则返回 `NULL`,同时原内存块保持不变。 - **特点**: - 如果 `ptr` 为 `NULL`,则等同于调用 `malloc(size)`。 - 如果 `size` 为零,行为取决于具体的库实现,可能释放内存并返回 `NULL`[^3]。 #### 对比总结 | 特性 | `malloc` | `calloc` | `realloc` | |----------------|-----------------------------------|---------------------------------------|-------------------------------------| | **初始化** | 不初始化 | 初始化为零 | 不改变原内存内容 | | **参数** | 单个参数:内存大小 | 两个参数:元素数量和单个元素大小 | 两个参数:原内存指针和新内存大小 | | **用途** | 分配未初始化的内存块 | 分配并初始化为零的内存块 | 调整已分配内存块的大小 | | **返回值** | 成功返回 `void*` 指针,失败返回 `NULL` | 同上 | 同上 | #### 示例代码 以下是一个简单的代码示例,展示了如何使用 `malloc`、`calloc` 和 `realloc`: ```c #include <stdio.h> #include <stdlib.h> int main() { // 使用 malloc 分配内存 int *p = (int *)malloc(5 * sizeof(int)); if (p == NULL) { perror("malloc failed"); return 1; } p[0] = 10; // 内存未初始化,需手动赋值 // 使用 calloc 分配内存 int *q = (int *)calloc(5, sizeof(int)); if (q == NULL) { perror("calloc failed"); return 1; } printf("q[0] = %d\n", q[0]); // 输出 0,因为内存已初始化为零 // 使用 realloc 调整内存大小 p = (int *)realloc(p, 10 * sizeof(int)); if (p == NULL) { perror("realloc failed"); return 1; } free(p); // 释放 mallocrealloc 分配的内存 free(q); // 释放 calloc 分配的内存 return 0; } ``` #### 注意事项 - 在使用 `malloc` 和 `realloc` 时,必须确保对分配的内存进行正确的初始化。 - 使用 `free` 释放内存时,只能释放由 `malloc`、`calloc` 或 `realloc` 分配的内存[^2]。 - 调用 `realloc` 时,如果传入的指针为 `NULL`,则等同于调用 `malloc`[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值