我们在这里看到的是关于 BoundsChecker 的一个令人讨厌的、鲜为人知的秘密:它根本无法让您看到结构成员。如果将数组声明为结构的一部分,无论该结构是自动分配还是动态分配,BoundsChecker 都会将该结构视为一个 blob。如果超出该结构的边界,它将报告问题。否则,没有。
也就是说,几年前我们编写了一些代码,这些代码目前随产品一起提供,并且可以使用隐藏的配置选项来调用。如果您要手动将该行EnableStructureMemberEnumeration=1
插入[BC MemoryTracker]
项目配置文件 ( .dpbcd
) 的部分,那么您会发现产品可以看到结构的成员(主要是结构和数组),只要该结构是自动分配的(在堆)。
不过,这个选项还没有完全准备好迎接黄金时段。它具有非常复杂的类和结构的问题,例如在 STL 中发现的。此外,在上面给出的具体测试用例中,还有另一个问题。它通常无法区分开始结构/类的数组和类对象本身。两者在内存中具有相同的地址。但是考虑一下这段代码:
struct _Type {
int Array[5];
} Objects[10];
struct _Type *pObject = &Objects[5];
int *pInt = &Objects[0].Array[5];
在这两种情况下,我们看到相同的地址,第一次的偏移量为 100,第二次的偏移量为 20。第一次,如果根据 评估Array
,则无效,但如果根据 评估Objects
,则有效。什么是糟糕的程序?
哦,还有一件事:BoundsChecker 通常会忽略对数组末尾之后的第一个元素的访问。这是因为存在大量代码,其中迭代器只会在最后一个元素。这是错误错误的巨大来源,因此有人将其更改为仅在溢出到达下一个位置(及更远位置)时才抱怨。这里的问题是,你增加了迭代器,但你真的要使用它吗?
因此,目前,问题的答案是 BoundsChecker 确实支持这种检查,但并非没有使用未记录的“功能”,也不是没有问题。