简体   繁体   English

地图C ++输出错误

[英]Wrong output with map C++

I wrote the following code for constructing std::pair as key to unordered_map. 我编写了以下代码,用于构造std :: pair作为unordered_map的键。 However, I dont know why I am getting all 0's as output of vector. 但是,我不知道为什么我的矢量输出全为0。 Can someone please suggest as to where am I going wrong? 有人可以建议我要去哪里吗?

struct key_hash
{
    size_t operator()(const std::pair<unsigned,unsigned>& key) const
    {
        return uint64_t((key.first << 32) | key.second);
    }
};

typedef std::unordered_map<std::pair<unsigned,unsigned>, std::vector<unsigned>, key_hash> MyMap;


int main()
{    
    MyMap m;
    vector<unsigned> t;
    t.push_back(4);
    t.push_back(5);
    m[make_pair(4294967292,4294967291)]=t;

    for(vector<unsigned>::iterator i=m[make_pair(4294967292,4294967291)].begin(),j=m[make_pair(2147483645,2147483643)].end();i!=j;++i)
        cout<<"vec="<<(*i)<<"\n";

    cout<<"vector empty. \n";
}

i and j are iterators to 2 different vector's and they cannot be compared. ij是2个不同向量的迭代器,无法进行比较。 Using debug iterators might catch this under visual studio. 使用调试迭代器可能会在Visual Studio中发现这一点。

This code: j=m[make_pair(2147483645,2147483643)].end(); 这段代码: j=m[make_pair(2147483645,2147483643)].end(); will create a new empty vector since the key is different from the previously used one. 将创建一个新的空向量,因为密钥与以前使用的密钥不同。

Whem initializing j like this: j=m[make_pair(4294967292,4294967291)].end(); Whem像这样初始化jj=m[make_pair(4294967292,4294967291)].end(); the results are fine: 结果很好:

vec=4 vec=5 vector empty.

您将获得不确定的行为,因为m[make_pair(4294967292,4294967291)]m[make_pair(2147483645,2147483643)]可能是不同的对象(除非发生与溢出包装非常奇怪的事情)。

  1. You may have a typo with the literals - just do key = make_pair(...u,...u) . 您可能会在文字上打错-只需执行key = make_pair(...u,...u)
  2. Your hash functor probably has an overflow - unsigned int is probably 32-bit on your system). 您的哈希函子可能有一个溢出-系统上unsigned int可能是32位。
  3. Your literals probably exceed the maximum value of signed integers, and are not specified to be unsigned. 您的文字可能超过有符号整数的最大值,并且未指定为无符号。

try changing your hash function to something along those lines: 尝试将您的哈希函数更改为以下内容:

struct key_hash
 {
     size_t operator()(const std::pair<unsigned,unsigned>& key) const
     {
         uint64_t tmp = key.first;
         tmp = tmp << 32;
         return uint64_t(tmp | key.second);                                                                                                                                                              
      }
 };

I have also added the one instance of the pair so changed the main to : 我还添加了一对货币对的一个实例,因此将main更改为:

MyMap m;
vector<unsigned> t;
t.push_back(4);
t.push_back(5);
auto a =  make_pair(4294967292,4294967291);
m[a]=t;

for(vector<unsigned>::iterator i=m[a].begin(),j=m[a].end();i!=j;++i)
    cout<<"vec="<<(*i)<<"\n";

cout<<"vector empty. \n";

This gave me the correct output: 这给了我正确的输出:

vec=4
vec=5
vector empty.

Tidying up the loop to make it clear (and ignoring the warning about a 32-bit left-shift on a 32-bit value...) 整理循环以使其清晰(并忽略有关32位值发生32位左移的警告...)

What you are doing is this: 您正在执行的操作是这样的:

const auto& first_vector = m[make_pair(4294967292,4294967291)];
const auto& second_vector = m[make_pair(2147483645,2147483643)];

for(auto iter = begin(first_vector) ; 
    iter != end(second_vector) ; // <<=== SEE THE PROBLEM?
    ++iter)
{
  // ...
}

Incrementing the iterator of one vector will never yield the end() of a different one so your loop is infinite, until you get a segfault because you've accessed memory that does not belong to you. 增加一个向量的迭代器永远不会产生另一个向量的end(),因此循环是无限的,直到遇到段错误,因为您访问了不属于您的内存。

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

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