Указатели каким-то образом аннулируются, что приводит к нарушению прав доступа.

Dev Environment — VS2010, а язык — смешанный C# (GUI) и C++ (Sim Engine), компилируемый для 32-битной Windows. Исключения возникают во всех протестированных нами версиях Windows, включая 32-разрядную версию XP, 32-разрядную версию Vista, 32-разрядную версию 7 и 64-разрядную версию 7.

Я в полной растерянности с этим. Из-за характера программы (моделирование на основе событий) указатель становится недействительным в какой-то неизвестный момент времени, прежде чем мы фактически попытаемся получить к нему доступ и получить AVE.

Что я действительно знаю, так это то, что оно аннулируется очень особым образом, и я надеюсь, что у кого-нибудь может быть идея относительно того, что может быть причиной этого. Когда происходит AVE, указатель, который он пытался использовать, был изменен на:

(original) - ((size * 2) - 1)  

Где original — исходный адрес, на который указывает указатель, а size — размер объекта, на который указывает указатель.

Например, одно из нарушений прав доступа произошло для указателя, который должен указывать на 0x58E0, а объект имел размер 0x70. Вместо того, чтобы указывать на 0x58E0, он указывал на 0x5801, который равен 0x58E0 - ((0x70 * 2) - 1). То же самое происходит с другим объектом другого типа и размера, так что это кажется очень специфическим отношением.

Изменить: выше я не говорю об арифметике указателя в коде, я только показываю математическую взаимосвязь между должным указателем и тем, чем он заканчивается когда мы ссылаемся на него и получаем исключение нарушения прав доступа. Надеюсь, это прояснит ситуацию.

Редактировать 2: я только что понял, что, насколько я помню, мы видели эту проблему только с объектами, которые являются членами стандартного вектора. Есть ли что-то, что мы могли облажаться в нашей векторной реализации, что могло вызвать такое поведение?


person gtftw    schedule 26.01.2012    source источник
comment
При выполнении арифметических операций с указателями единицей измерения является один объект, а не один байт. Так что умножение на размер кажется проблематичным; дважды проверьте, понимаете ли вы арифметику указателей. Возможно, вы просто имеете в виду original - 1.   -  person Kerrek SB    schedule 26.01.2012
comment
@KerrekSB под переменной original он, вероятно, имеет в виду исходный адрес объекта, интерпретируемый как целое число   -  person Seth Carnegie    schedule 26.01.2012
comment
Извините, я недостаточно ясно выразился в посте. Я не делаю никакой арифметики указателя в коде, вышеприведенное было только для того, чтобы показать математическую связь между тем, каким должен быть указатель должен, и тем, чем он становится, когда мы пытаемся сослаться на (сейчас) неверный указатель и получить исключение нарушения прав доступа.   -  person gtftw    schedule 26.01.2012
comment
Вы пробовали использовать точку останова данных, чтобы получать уведомления при изменении указателя?   -  person Eric Fortin    schedule 26.01.2012
comment
Я пытался, но так как это смешанное приложение, VS не позволит мне его создать. В настоящее время я пытаюсь найти способ обойти это.   -  person gtftw    schedule 26.01.2012


Ответы (2)


Характер повреждения предполагает, что кто-то напортачил с использованием realloc.

person Joshua    schedule 26.01.2012
comment
Я только что выполнил поиск в VS для realloc, и он ничего не нашел, поэтому мы не вызываем его напрямую. В случае, если это имеет какое-либо значение, насколько я могу думать, кажется, что эта проблема наблюдалась только с объектами, которые являются членами векторов. Что-нибудь, что я мог бы найти в нашей векторной реализации, что могло бы вызвать такую ​​​​проблему? - person gtftw; 26.01.2012
comment
Ну вот. Вектор вызывает realloc. Вместо этого попробуйте хранить указатели на объекты в векторе. - person Joshua; 26.01.2012

Я только что понял, что, насколько я помню, мы видели эту проблему только с объектами, которые являются членами стандартного вектора. Есть ли что-то, что мы могли облажаться в нашей векторной реализации, что могло вызвать такое поведение?

Проблема не в реализации вектора, а в том, как вы его используете.

vector определенно делает недействительными итераторы и указатели на существующие объекты всякий раз, когда он увеличивает свою емкость. Своеобразная математическая взаимосвязь, которую вы видите, будет связана с моделью роста вашей конкретной реализации.

Решение состоит в том, чтобы не сохранять указатель на содержимое вектора при изменении размера вектора. Вы можете сохранить указатель на вектор и индекс, которые останутся действительными.

person Ben Voigt    schedule 26.01.2012
comment
Я должен был быть более конкретным: наш вектор хранит только указатели на объекты. То, о чем вы говорите, все еще применимо в этом случае? Кроме того, это произошло по крайней мере один раз с объектом, на который указывал вектор, который когда-либо имел только 1 элемент за все время сценария. - person gtftw; 26.01.2012
comment
@gtftw: я не понимаю, как это объекты, которые являются членами std::vector. Если у вас есть указатель, а также копия этого указателя в векторе, то вектор не имеет к этому никакого отношения. Или указатель, хранящийся в векторе, изменяется? - person Ben Voigt; 26.01.2012