Я использую std :: map с пользовательским классом сравнения и пользовательскими классами в качестве ключа
Теперь я использую оператор [] для доступа к элементам по ключу. Это, однако, кажется, создает большую проблему. Карта, кажется, неправильно распределяет элементы, или они становятся поврежденными. Это становится очевидным, потому что мой пользовательский класс сравнения выдает исключение, когда обнаруживает, что один из сравниваемых объектов имеет произвольные значения, хранящиеся в его полях данных (что, по-видимому, подразумевает, что конструктор не выполнялся или что объект никогда не создавался в первое место)
Теперь обнаруживается другое несоответствие:
Когда я вызываю std :: map :: size () и сравниваю его с количеством раз, я могу увеличить итератор begin (), чтобы добраться до итератора end (), тогда они не совпадают.
В частности, карта сообщает о большем размере (), чем она, по-видимому, содержит.
Класс, который я использую в качестве ключа, является классом матрицы с полями данных:
unsigned int
unsigned int
vector<vector<Another Class>>
Однако ни в одном из этих классов я не использую арифметику указателей или что-либо еще, что могло бы напрямую манипулировать памятью. Также у меня нет пользовательских конструкторов копирования ни в одном из используемых классов.
РЕДАКТИРОВАТЬ: функция сравнения
struct SymModMatComp
{
bool operator()(const ModMat& mat1, const ModMat& mat2) const
{
unsigned int rows = mat1.get_row_number();
unsigned int columns = mat1.get_column_number();
if(mat2.get_row_number() != rows || mat2.get_column_number() != columns)
{
throw dimension_mismatch();
}
for(unsigned int i = 0; i < rows; i++)
{
for(unsigned int j = 0; j < columns; j++)
{
if(mat1.get_item(i,j).get_value() < mat2.get_item(i,j).get_value())
{
return true;
}
else if(mat1.get_item(i,j).get_value() > mat2.get_item(i,j).get_value())
{
return false;
}
}
}
return false;
}
}
get_value () возвращает беззнаковое целое
РЕШИТЬ:
Я использовал valgrind, чтобы проверить наличие ошибок доступа к памяти … Я обнаружил, что совершенно не связанная часть программы activallz снова и снова удаляет уже удаленный объект ….
Кажется, это повредило пространство, в котором хранятся элементы на карте.
Спасибо за все хорошие идеи, хотя!
Без кода сложно догадаться, однако я все равно попробую.
Знаете ли вы, что T& оператор [] (const key_type& Икс ); вставить значение в карту, если ключ не существует? Таким образом, размер карты увеличится на единицу, если у вас еще нет ключа на карте.
Элемент будет создан с использованием конструктора по умолчанию.
Если вы испытываете коррупцию с map
со сложными определяемыми пользователем ключами, вполне вероятно, что ваша функция сравнения не соответствует требованиям строгий слабый порядок:
!(x < x)
!(x < y && y < x)
x < y && y < z -> x < z
!(x < y || y < x || y < z || z < y) -> !(x < z || z < x)
Если какое-либо из этих требований не будет выполнено, возникнет неопределенное поведение (например, повреждение памяти).
Если матрица участвует в функции сравнения, простой способ обеспечить строгое слабое упорядочение состоит в использовании лексикографического упорядочения для ее элементов.