Нарушение прав доступа при объявлении переменной - PullRequest
0 голосов
/ 24 января 2012

Я ударил немного стены с некоторой отладкой.Я получил две ошибки нарушения доступа в совершенно не связанных частях моей программы, ни одну из них я не понимаю.Одна из них возникает, когда я объявляю новую переменную, в данном случае,

std::map<float, float> fMap;

Я проверил, что имя не используется где-либо еще в коде, я не уверен, насколько это уместно, ноэто все, что я могу придумать.Я думаю, что мне когда-либо удавалось создать один из них, когда я делаю что-то глупое с указателем.У кого-нибудь есть идеи, что может быть причиной этого?Проект компилируется с Borland 6.

Спасибо,

Ответы [ 3 ]

2 голосов
/ 24 января 2012

Ошибка не имеет ничего общего с имеющимся объявлением: скорее всего, это задержанное последствие ошибки, которую вы сделали ранее.Некоторый код, который выполнялся до попадания в объявление карты, так или иначе повредил кучу.Вещи, которые могут потенциально привести к "отложенному" сбою:

  • Освобождение памяти, которая не была выделена вам
  • Освобождение памяти несколько раз
  • Запись вне области памяти, которая была выделена вам

Эти ошибки могут немедленно вызвать сбой, но часто это не так: вместо этого поврежденный фрагмент некоторой чувствительной структуры кучи ожидает своего появления.выделено для запуска аварии.Когда std::map выделяет память для своих внутренних устройств, он вызывает сбой, запрашивая память из поврежденной кучи.

Лучший способ выяснить это - использовать инструмент профилирования памяти.Он должен точно указать вам ошибку в тот момент, когда она возникает, и позволить вам решить проблему, а не преследовать ее последствия.

0 голосов
/ 24 января 2012

Это, безусловно, результат более ранней ошибки - что-то, что вы сделали, это неопределенное поведение, возможно, что-то, связанное с неверным указателем или ссылкой, или неправильное использование указателя.Одна из наиболее частых причин - запись за концом выделенного блока или запись через висячий указатель (память уже удалена).Часто это может быть очень скрытым, например:

std::vector<int> v;
v.push_back(1);
int& r = v[0];
v.push_back(2);
r = 0;

Добавление или удаление элементов из контейнера может при определенных обстоятельствах (которые зависят от типа контейнера) сделать недействительными все ссылки или указатели на элементы в контейнере.

Еще во времена C одной из наиболее распространенных причин было выделение strlen байтов, а затем strcpy в них.Если вы используете современный C ++, вы никогда не размещаете массивы чего-либо, и наиболее распространенной причиной, вероятно, является вставка в контейнер, делающий недействительным указатель, ссылку или итератор, который все еще используется.Использование отладочной версии библиотеки поможет решить проблемы с итераторами;такие инструменты, как valgrind, обычно улавливают проблемы с указателями и ссылками.Вы должны использовать оба варианта (вместе с хорошими тестовыми наборами - ни один не обнаружит ошибок, которые не встречаются в тестовых примерах).

0 голосов
/ 24 января 2012

Не используйте float в качестве ключей для std :: maps, операторы сравнения не очень хорошо работают с плавающими точками. Можете ли вы дать мне более подробную информацию о других ошибках?

...