C语言使用realloc重分配内存时如何将新增内存初始化为0
char数组动态扩容时仅对新增内存做0初始化的实现方法
核心思路是自行维护内存块的新旧长度,在realloc()调用成功后,精准定位新增内存的起始位置,仅对这部分内存执行0值写入,完全不触碰原有已存储数据的区域。
实现步骤
- 维护两个长度变量:
old_size记录当前内存块已分配的总字节数,new_size记录本次扩容后需要的总字节数。 - 调用
realloc()时先用临时指针接收返回值,避免分配失败时原指针被覆写为NULL,造成内存泄漏。 - 若扩容成功且
new_size > old_size,新增内存的起始地址为「数组指针 + old_size」,从该位置开始将长度为new_size - old_size的内存块置0即可。 - 最后更新长度记录,将临时指针赋值给原数组指针。
可直接参考的代码示例
#include <stdlib.h> #include <string.h> // 动态扩容char数组的工具函数 char* char_array_resize(char* arr, size_t* current_cap, size_t new_cap) { if (new_cap == 0) { free(arr); *current_cap = 0; return NULL; } char* temp = (char*)realloc(arr, new_cap); if (temp == NULL) { // 扩容失败返回NULL,原数组指针仍有效 return NULL; } // 仅当新长度大于旧长度(即扩容场景)时,初始化新增部分 if (new_cap > *current_cap) { memset(temp + *current_cap, 0, new_cap - *current_cap); *current_cap = new_cap; } return temp; } int demo() { // 首次分配用calloc,直接获得全0的初始内存 size_t cap = 16; char* arr = (char*)calloc(cap, sizeof(char)); if (arr == NULL) return -1; // 模拟第一次扩容到32字节 char* new_arr = char_array_resize(arr, &cap, 32); if (new_arr == NULL) { free(arr); return -1; } arr = new_arr; // 模拟第二次扩容到64字节 new_arr = char_array_resize(arr, &cap, 64); if (new_arr == NULL) { free(arr); return -1; } arr = new_arr; // 业务逻辑使用数组... free(arr); return 0; }
关键说明
- 不需要额外判断
realloc()是原地扩容(原内存块后直接拼接空闲空间)还是异地扩容(重新找足够大的内存块、拷贝原有数据):两种场景下原有数据的长度都是old_size,新增区域都位于内存块偏移old_size的位置,上述初始化逻辑完全通用。 - 禁止对
realloc()返回的整个内存块做全量0初始化,否则会覆盖数组中已经存储的有效数据。 - 必须自行维护当前内存块的长度,C语言标准没有提供从指针反查指向内存块大小的接口,依赖隐式行为会造成越界访问。
内容的提问来源于stack exchange,提问作者Lakshay Rohila
相关产品推荐
相关产品推荐

