映射C 的输出错误

Wrong output with map C++

本文关键字:错误 输出 映射      更新时间:2023-10-16

我编写了以下代码,用于构造std :: Pair作为unordered_map的键。但是,我不知道为什么我将全部0作为向量的输出。有人可以建议我出错了哪里吗?

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 J 是迭代器到2个不同的向量,无法比较它们。使用调试迭代器可能会在Visual Studio下捕获。

此代码:j=m[make_pair(2147483645,2147483643)].end();将创建一个新的空矢量,因为密钥与先前使用的键不同。

惠姆初始化 J 喜欢:j=m[make_pair(4294967292,4294967291)].end();结果很好:

vec=4 vec=5 vector empty.

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

  1. 您可能有一个带有文字的错别字 - 只需做key = make_pair(...u,...u)
  2. 您的哈希函子可能具有溢出-unsigned int可能在您的系统上32位)。
  3. 您的文字可能超过签名整数的最大值,并且未指定为未签名。

尝试将您的哈希函数更改为这些行:

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);                                                                                                                                                              
      }
 };

我还添加了这对的一个实例,因此将主更改为:

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";

这给了我正确的输出:

vec=4
vec=5
vector empty.

整理循环以使其清除(并且忽略了32位值的32位左移的警告...)

您正在做的是:

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)
{
  // ...
}

增加一个向量的迭代器将永远不会产生一个不同的末端(),因此您的循环是无限的,直到您获得segfault,因为您已经访问了不属于您的内存。