使用指向内存分配块中间的指针调用free是否符合ANSI C规范?
关于free()传入非malloc原始指针的合规性问题
核心结论:这种直接free指向内存块中间地址的用法完全不符合ANSI C标准,属于标准定义的未定义行为。
标准依据:ANSI C(包括C89、C99、C11等所有后续标准)明确规定,
free()函数的参数必须是以下两种情况之一:- 此前由
malloc()、calloc()或realloc()函数返回的指针; - NULL指针。
若传入的是指向已分配内存块中间位置的指针,标准将其归类为未定义行为——标准不对这种操作的结果做任何保证,程序可能崩溃、破坏堆结构、产生静默数据错误,甚至在某些平台上看似正常运行,但这都属于偶然情况,并非合规表现。
- 此前由
BString场景的正确做法:对于将长度存储在数据指针前方的BString实现,正确的释放逻辑是先通过指针计算回溯到
malloc()返回的原始起始地址,再调用free()。例如:// 假设ptr是指向字符串数据的指针,长度存在ptr前的size_t空间 free((char*)ptr - sizeof(size_t));直接free数据指针的做法是错误的,完全依赖非标准的库实现细节。
移植性说明:由于这是未定义行为,该用法不具备跨合规编译器/标准库的移植性。部分特定平台或自定义内存分配库可能允许这种操作,但这属于实现私有的扩展,而非标准要求,更换环境后必然引发问题。
内容的提问来源于stack exchange,提问作者Rich Remer
相关产品推荐
相关产品推荐

