“错误:只读位置的分配”在 unordered_map (C++) 中

发布于 2024-08-12 10:16:32 字数 1578 浏览 6 评论 0原文

我有一个尴尬的哈希表(具体来说,一个 unordered_map),其中包含 int 键和 vector向量< int>> 数据。我需要定期更新这个二维整数向量中的元素。没有什么内在原因我不能这样做,对吗?我切换到的较新的 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) 中。当我没有紧迫的期限时,我会尝试更仔细地剖析错误!

I have an awkward hash table (specifically, an unordered_map) with int keys and vector< vector< int >> data. I periodically need to update elements in this two-dimensional vector of ints. There's no intrinsic reason I shouldn't be able to, right? A newer g++ compiler I've switched to complains of an assignment of read-only location on the line designated below.

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

I'm new to C++, so nothing's too obvious. Thank you for any help.


Following Tim's suggestion

I've replaced the relevant parts of code above with the following:

  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
    }

This code compiles without the error and appears to run fine. Like Tim, I still don't quite understand why the fix works. The error was previously appearing with gcc version 4.1.2 20080704 (Red Hat 4.1.2-44) but not with gcc version 4.0.1 (Apple Inc. build 5465). I will try to dissect the error more carefully when I'm not under a tight deadline!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

锦爱 2024-08-19 10:16:32

您确定每个第一级向量中确实有 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 );

Are you sure there really are thisStep + 1 elements in every first-level vector and NUM_DEMES elements in every second-level vector?

You're not actually assigning to a map iterator, if I read correctly, so I suspect the error is in the vector access.

It may be helpful to break that last statement up into multiple statements so that only one thing is being done on each to narrow down where the problem is. e.g.,

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

By the way, piItr = phenotypeIs.begin(); has no effect here, it could be simply:

pimap::iterator piItr = phenotypeIs.find( thisP );
卷耳 2024-08-19 10:16:32
( piItr -> second )[ thisStep ].at( d )

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

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

at() returns an iterator into the inner vector, not access to the value. What you want is

 *(( piItr -> second )[ thisStep ].at( d ))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文