reallocarray函数用法及注意事项
reallocarray函数用法及注意事项
reallocarray 是某些类 Unix 系统(如 OpenBSD、FreeBSD)提供的一个内存分配函数,用于替代 realloc,主要目的是在动态分配内存时避免因整数溢出导致的安全漏洞。它特别适用于需要分配多个元素的内存场景(例如数组扩容),并自动检查元素数量与大小的乘积是否溢出。
函数原型
1 |
|
- 参数:
ptr: 已分配内存的指针(可以是NULL)。nmemb: 需要分配的元素数量。size: 每个元素的大小。
- 返回值:
- 成功时返回新内存的指针,失败返回
NULL,且原内存块保持不变。
- 成功时返回新内存的指针,失败返回
核心功能
- 重新分配内存:类似
realloc,可以扩大或缩小内存块。 - 溢出检查:自动检查
nmemb * size是否溢出。若溢出,直接返回NULL并设置errno为ENOMEM。
典型用法示例
1 | int *arr = malloc(10 * sizeof(int)); // 初始分配 |
注意事项
可移植性:
reallocarray并非 C 标准库函数,仅在部分系统(如 OpenBSD、FreeBSD)中可用。- 在 Linux 中需定义
_GNU_SOURCE宏(通过#define _GNU_SOURCE)并包含<stdlib.h>。 - Windows 或其他平台可能需要手动实现或替换为
realloc+ 溢出检查。
错误处理:
- 必须检查返回值:若返回
NULL,原内存块(ptr)仍有效,需手动决定是否释放。 - 若
ptr为NULL,则行为类似malloc(nmemb * size),但仍检查溢出。
- 必须检查返回值:若返回
与
realloc的区别:realloc的调用形式为realloc(ptr, nmemb * size),但不会检查乘法溢出。reallocarray显式分离nmemb和size,并在计算总大小时检查溢出,更安全。
释放内存:
- 使用
free释放由reallocarray分配的内存,与malloc/realloc一致。
- 使用
旧指针处理:
- 若
reallocarray失败,原指针ptr仍指向有效内存,需根据业务逻辑决定是否继续使用或释放。
- 若
替代方案(不可用时)
如果系统不支持 reallocarray,可手动实现类似逻辑:
1 |
|
应用场景
- 动态数组扩容(如
vector实现)。 - 处理用户输入或不可信数据时分配内存,避免溢出攻击。
- 需要高安全性的内存分配操作。
使用时需结合系统环境权衡可移植性与安全性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!
