简体   繁体   English

std :: map :: size()与迭代器不同

[英]std::map::size() differs from iterators

I use a std::map with a custom comparison class and custom classes as key 我使用带有自定义比较类和自定义类作为键的std :: map

Now I use the operator[] to access elements by key. 现在,我使用operator []通过键访问元素。 This however seems to create a big problem. 但是,这似乎造成了一个大问题。 The map seems to incorrectly allocate elements or they become corrupt. 映射似乎错误地分配了元素,否则它们将损坏。 This becomes obvious because my custom comparison class throws an exception when it detects that one of the objects it compares has arbitrary values stored in its data fields (which seems to imply that the constructor didn't run or that the object was never created in the first place) 这很明显,因为我的自定义比较类在检测到它比较的一个对象在其数据字段中存储了任意值时抛出异常(这似乎暗示构造函数未运行或从未在对象中创建该对象)。第一名)

Now another discrepancy shows up: 现在出现另一个差异:

When I call std::map::size() and compare it to the number of times I can increment a begin() iterator to get to the end() iterator then they don't match. 当我调用std :: map :: size()并将其与我可以增加begin()迭代器到end()迭代器的次数进行比较时,它们不匹配。

Specifically the map reports a larger size() than it apparently contains. 具体来说,地图报告的size()大于其明显包含的size()。

The class I use as key is a custom matrix class with data fields: 我用作键的类是带有数据字段的自定义矩阵类:

unsigned int
unsigned int
vector<vector<Another Class>>

However in none of these classes do I use pointer arithmetic or anything else that could manipulate memory directly. 但是,在这些类中,没有一个使用指针算术或其他可以直接操作内存的方法。 Also I don't have custom defined copy constructors in any of the classes that are used. 另外,我在使用的任何类中都没有自定义定义的副本构造函数。

EDIT: Comparison Function 编辑:比较功能

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() returns an unsigned int get_value()返回一个无符号的int

SOLVED: 解决了:

I used valgrind to check for any memory access errors... I found out that a totally unrelated part of the program actuallz did do a delete on an already deleted object over and over .... 我用valgrind检查是否有任何内存访问错误...我发现程序reallz的一个完全不相关的部分确实在一遍又一遍地对已经删除的对象进行了删除。

That seems to have corrupted the space the map stored items in. 这似乎已损坏了地图存储项目的空间。

Thanks for all the good ideas though! 谢谢所有的好主意!

Without code it is difficult to guess, however I will try anyway. 没有代码,很难猜测,但是我还是会尝试。

Are you aware that T& operator[] ( const key_type& x ) ; 您是否知道T&operator [](const key_type&x) ; insert the value in the map if the key is not there? 如果键不存在,将值插入地图吗? So, the map size will increase by one if you haven't the key in the map already. 因此,如果您还没有地图中的键,则地图大小将增加一。

The element will be created using the default constructor. 元素将使用默认构造函数创建。

If you're experiencing corruption with a map with complex user-defined keys, it's likely that your comparison function does not respect the requirements of a strict weak ordering : 如果您在使用带有复杂的用户定义键的map时遇到损坏,则您的比较功能可能不符合严格的弱排序要求

  • irreflexivity: !(x < x) 不自反性: !(x < x)
  • asymmetry: !(x < y && y < x) 不对称: !(x < y && y < x)
  • transitivity: x < y && y < z -> x < z 传递性: x < y && y < z -> x < z
  • transitivity of incomparability: !(x < y || y < x || y < z || z < y) -> !(x < z || z < x) 不可比的传递性: !(x < y || y < x || y < z || z < y) -> !(x < z || z < x)

If any of these requirements are not met, undefined behaviour (eg memory corruption) will result. 如果不满足任何这些要求,将导致未定义的行为(例如,内存损坏)。

If the matrix participates in the comparison function, an easy way to ensure a strict weak ordering is to use lexicographic ordering on its elements. 如果矩阵参与比较功能,则确保严格的弱排序的一种简单方法是对其元素使用字典顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM