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!