一句话区别
- malloc:新建一块堆内存,只负责分配,不能修改已经分配好的内存大小
- realloc:重新调整一块已经存在的堆内存大小(扩大、缩小都可以)
1. 函数原型
// 分配 size 字节,返回起始地址,内容初始是随机脏数据 void *malloc(size_t size); // 调整 ptr 指向内存块为 size 字节 void *realloc(void *ptr, size_t size);2. 详细对比
malloc
- 输入:需要的字节数
size - 作用:在堆上开辟全新内存
- 如果分配成功:返回内存首地址;失败返回
NULL - 不会保留任何旧数据,新内存里是随机值
malloc(0)行为是未定义/由平台决定,尽量不要写
realloc
realloc(ptr, new_size)分几种情况:
- ptr == NULL:等价于
malloc(new_size),分配新内存
realloc(NULL, 100) == malloc(100);- new_size == 0:等价于
free(ptr)(不同平台有差异,不推荐这么释放) - 原有内存块后面有足够空闲空间:原地扩容,返回原来的 ptr,原有数据保留
- 后面空间不够:在堆别的地方找一块符合大小的新内存,把旧内存的数据拷贝过去,然后自动 free 旧内存,返回新地址
- 分配失败:返回
NULL,原来那块内存不会被 free,还能用!
⚠️ 经典坑:不要直接
ptr = realloc(ptr, newsize);如果失败返回 NULL,你原来的 ptr 直接丢了 → 内存泄漏!
正确写法:
void *tmp = realloc(ptr, new_size); if (tmp != NULL) { ptr = tmp; }
3. 对比表格
| 特性 | malloc | realloc |
|---|---|---|
| 功能 | 分配新堆内存 | 修改已有堆内存大小(扩容/缩容) |
| 参数 | 只有目标大小 | 旧内存指针 + 新大小 |
| 旧数据 | 无,新内存脏数据 | 保留原来的数据 |
| 是否自动 free 旧内存 | 不会 | 搬迁扩容时自动 free 旧块 |
| 输入 NULL | 不支持(分配新内存) | 等价 malloc |
4. 补充:calloc
顺带一提(经常一起问)
void *calloc(size_t nmemb, size_t size);分配nmemb * size字节,并且全部初始化为 0。
malloc 不初始化、calloc 清零。
5. 简单示例
// malloc 分配 int *p = malloc(5 * sizeof(int)); // realloc 扩容到 10 个 int int *tmp = realloc(p, 10 * sizeof(int)); if (tmp) { p = tmp; }