You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测C++中Placement New创建对象的越界访问(内存块内)

检测Placement New对象的边界越界访问

示例代码

#include <iostream>

struct mix {
  int64_t x[10];
};

int main() {
  int64_t* p = new int64_t[100];
  mix* px = new (p) mix;
  mix* py = new (p + 10) mix;
  px->x[12] = 104;
  std::cout << py->x[2] << std::endl;
  delete[] p;
}

问题背景

这段代码里,px和py是在同一块分配的内存中通过placement new构造的对象。访问px->x[12]时,虽然没超出总内存块p的范围,但已经越界了mix对象自身的边界。

常规的-fsanitize=address、默认配置的-fsanitize=undefined和Valgrind都不会报告这种越界,因为它们只检查是否超出了分配的内存块整体边界,而非单个对象的边界。现在需要一种无需修改源代码、允许性能损失的方案,来严格检测这类跨对象的越界访问。

可行方案

1. Clang 启用object-size UBSan检测

Clang的UndefinedBehaviorSanitizer(UBSan)提供了object-size检测选项,它会跟踪每个对象的实际大小,检查访问是否超出对象自身的边界,哪怕内存仍在全局分配块内。编译时添加参数:

clang++ -fsanitize=undefined,object-size -o test test.cpp

运行程序后,会直接触发报错,明确指出px->x[12]越界访问了mix对象的成员数组。

2. GCC 启用bounds-strict UBSan检测

GCC 10及以上版本支持bounds-strict选项,属于UBSan的扩展,它会严格校验数组下标是否在对象自身的边界内,而非仅看分配的内存块。编译命令:

g++ -fsanitize=undefined,bounds-strict -o test test.cpp

运行后同样会捕获到px->x[12]的越界行为。

3. Intel Inspector 动态检测

Intel Inspector是一款专业的内存错误检测工具,能够识别通过placement new创建的对象边界,检测对象内部的越界访问。只需将编译后的程序导入Inspector,运行内存错误检测任务,就能定位到该问题。

4. Clang Static Analyzer 静态分析

Clang静态分析器可以在编译阶段就识别出这类对象越界访问。执行以下命令进行分析:

clang++ --analyze -Xanalyzer -analyzer-checker=core test.cpp

分析后会输出针对px->x[12]的越界警告,无需运行程序就能提前发现问题。

内容的提问来源于stack exchange,提问作者种传龙

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 01:31:00