【问题标题】:"error: assignment of read-only location" in unordered_map (C++)unordered_map (C++) 中的“错误:分配只读位置”
【发布时间】:2009-11-19 00:20:10
【问题描述】:

我有一个带有 int 键和 vector< vector< int >> 数据的尴尬哈希表(特别是 unordered_map)。我需要定期更新这个二维整数向量中的元素。没有内在的原因我不应该这样做,对吧?我切换到的较新的 g++ 编译器抱怨在下面指定的行上分配了只读位置。

typedef std::tr1::unordered_map< int, vector< vector< int > > > pimap;

vector< Strain * > liveStrains;
pimap phenotypeIs;
int NUM_DEMES = 3;

...
vector< Strain * >::const_iterator lsItr;
for ( lsItr = liveStrains.begin(); lsItr != liveStrains.end(); ++lsItr ) {
 int thisP = (*lsItr)->getPhenotype();
 pimap::iterator piItr = phenotypeIs.begin();
 piItr = phenotypeIs.find( thisP );
 if ( piItr != phenotypeIs.end() ) {
   for ( int d = 0; d < NUM_DEMES; d++ ) {
      ( piItr -> second )[ thisStep ].at( d ) = (*lsItr)->getI( d );  // error here
   }
 }
}

我是 C++ 新手,所以没有什么太明显了。感谢您的帮助。


听从蒂姆的建议

我已将上述代码的相关部分替换为以下内容:

  pimap::iterator piItr = phenotypeIs.find( thisP );
  if ( piItr != phenotypeIs.end() ) {
    for ( int d = 0; d < NUM_DEMES; d++ ) {
      vector< vector< int > > & thisVec2 = piItr->second;
      vector<int> & thisVec = thisVec2.at( thisStep );
      int & ii = thisVec.at( d );
      ii = (*lsItr)->getI( d );
      // ( piItr -> second )[ thisStep ].at( d ) = (*lsItr)->getI( d ); // error was here
    }

此代码编译时没有错误,并且运行良好。像蒂姆一样,我仍然不太明白为什么修复有效。该错误以前出现在 gcc 版本 4.1.2 20080704 (Red Hat 4.1.2-44) 但不是 gcc 版本 4.0.1 (Apple Inc. build 5465)。当我没有紧迫的最后期限时,我会尝试更仔细地剖析错误!

【问题讨论】:

  • (*lsItr)-&gt;getI( d ) 返回什么?
  • (*lsItr)->getI(d) 返回一个整数。 (真的。)
  • @Tim 谢谢我弄错了:)

标签: c++ iterator unordered-map


【解决方案1】:

您确定每个一级向量中确实有thisStep + 1 元素,每个二级向量中确实有NUM_DEMES 元素吗?

如果我没看错,你实际上并没有分配给映射迭代器,所以我怀疑错误出在向量访问中。

将最后一个语句分解为多个语句可能会有所帮助,这样每个语句只做一件事以缩小问题所在。例如,

Strain* strain = *lsItr;
vector<vector<int> >& vv = piItr->second;
vector<int>& v = vv[thisStep];
int& i = v.at(d);     // <-- My bet is that the error occurs here or the prev. line
i = strain->getI( d );

顺便说一句,piItr = phenotypeIs.begin();在这里没有任何作用,可能只是:

pimap::iterator piItr = phenotypeIs.find( thisP );

【讨论】:

  • 当我用您建议的更长的“未打包”版本替换该行时,错误消失了,事情似乎运行正常。我将在一个小时左右的时间内对其进行广泛的测试。非常感谢您对语法的帮助...这意味着我最初的语法存在问题。 (作为记录,有一次,我有一个旧的编译器无法处理没有指向某个地方的迭代器声明,所以我养成了将它们分配给 .begin() 的习惯。)
  • 奇怪,就实际调用的方法和运算符而言,它应该 100% 相同。您可能在 g++ 或其 STL 中发现了错误。您可以一次又一次地折叠它以尝试找出问题,但为了清楚起见,最好将其展开。
【解决方案2】:
( piItr -> second )[ thisStep ].at( d )

at() 将迭代器返回到内部向量中,而不是访问该值。你想要的是

 *(( piItr -> second )[ thisStep ].at( d ))

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多