То, что мы видим здесь, является неприятным, малоизвестным секретом о BoundsChecker: он вообще не дает вам представления о членах структуры. Если вы объявите массив как часть структуры, независимо от того, будет ли эта структура выделена автоматически или динамически, BoundsChecker увидит структуру как большой двоичный объект. Если вы выйдете за пределы этой структуры, она сообщит о проблеме. В противном случае, нет.
Тем не менее, несколько лет назад мы написали некоторый код, который поставляется вместе с продуктом в настоящее время, и который может быть вызван скрытой опцией конфигурации. Если бы вы вручную вставили строку 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 действительно поддерживает этот вид проверки, но не без недокументированной «функции» и не без проблем до сих пор.