malloc分配块前置头部:两种指针算术写法是否触发C/C++未定义行为
两段代码的合规性结论
C 语言环境
两段代码均完全符合C标准要求,不存在未定义行为:
- 第一段(Header*指针算术实现)
- 你定义的
Header使用alignas(max_align_t)保证了结构体对齐满足所有基本类型的对齐要求,original_hdr_ptr + 1是长度为1的Header数组的合法尾后指针,C标准允许获取数组尾后地址(只要不解引用该地址的Header类型对象)。 - 将尾后地址转换为
int*后写入数据时,malloc返回的无有效类型内存会被自动设置有效类型为int,完全符合有效类型规则,没有越界访问问题。 - 反向偏移恢复头部指针时,从合法的
Header尾后地址偏移-1回到有效Header对象起始地址,操作完全合法,得到的new_hdr_ptr是可用的有效指针。
- 你定义的
- 第二段(char*指针算术实现)
这是最稳妥、兼容性最好的写法:C标准明确允许char*类型指针遍历任意内存块的字节,按sizeof(Header)偏移的操作完全不受指针类型约束,不存在任何合规性风险,也是绝大多数同类开源库(sds、stb_ds等)实际采用的实现方式。
C++ 环境
两段代码仅需要补充Header对象的构造逻辑即可规避未定义行为:
- 你当前代码中直接对
malloc返回的内存赋值size和capacity属于访问未构造的非平凡初始化对象,是C++标准规定的未定义行为。只需要在分配内存后添加placement new构造即可:
Header *original_hdr_ptr = static_cast<Header*>(malloc( sizeof( Header ) + sizeof( int ) * 100 )); new(original_hdr_ptr) Header{0, 100}; // 补充这行构造Header对象即可
- 补充构造逻辑后,两段的指针算术操作均符合C++标准要求,其中char*偏移的写法依然是兼容性最好的选择。
内容的提问来源于stack exchange,提问作者Jackson Allan
相关产品推荐
相关产品推荐

