2

我使用带有自定义比较类和自定义类的 std::map 作为键

现在我使用 operator[] 按键访问元素。然而,这似乎造成了一个大问题。地图似乎错误地分配了元素或它们变得损坏。这变得很明显,因为当我的自定义比较类检测到它比较的对象之一在其数据字段中存储了任意值时(这似乎暗示构造函数没有运行或对象从未在第一名)

现在出现了另一个差异:

当我调用 std::map::size() 并将其与我可以递增 begin() 迭代器以到达 end() 迭代器的次数进行比较时,它们不匹配。

具体来说,地图报告的 size() 比它明显包含的要大。

我用作键的类是一个带有数据字段的自定义矩阵类:

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 检查是否有任何内存访问错误...我发现程序actuallz 的一个完全不相关的部分确实一遍又一遍地对已删除的对象进行了删除...。

这似乎破坏了地图存储项目的空间。

感谢所有的好主意!

4

2 回答 2

1

没有代码很难猜测,但无论如何我都会尝试。

你知道T& operator[] ( const key_type& x ) ; 如果键不存在,则在地图中插入值?因此,如果您还没有地图中的键,则地图大小将增加一。

该元素将使用默认构造函数创建。

于 2012-10-29T10:52:01.817 回答
0

如果您在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)

如果不满足这些要求中的任何一个,将导致未定义的行为(例如内存损坏)。

如果矩阵参与比较函数,确保严格弱排序的一种简单方法是对其元素使用字典顺序。

于 2012-10-29T10:53:55.613 回答