【问题标题】:C++ rend() points to the same element as rbegin()C++ rend() 指向与 rbegin() 相同的元素
【发布时间】:2016-08-16 21:26:26
【问题描述】:

运行下面的代码,我希望看到测试 1 的第 4 个值的不同地址(与值 1 和 3 不同)。这表明rend() 与rbegin() 相同?? 我也不希望循环经历第二次迭代并出现段错误。

知道我做错了什么吗?

map<unsigned long, int*> newMap;
newMap[13] = new int(1340);
cout << "test 1:" << endl;
cout << &(*(newMap.begin())) << endl;
cout << &(*(newMap.end())) << endl;
cout << &(*(newMap.rbegin())) << endl;
cout << &(*(newMap.rend())) << endl;
cout << "test 2:" << endl;
for(map<unsigned long, int*>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){
  cout << "next iteration" << endl;
  map<unsigned long, int*>::reverse_iterator entry = it;
  it++;
  delete entry->second;
  newMap.erase(entry->first);
}

输出:

test 1:
0x2299050
0x7fffcd574908
0x2299050
0x2299050
test 2:
next iteration
next iteration
*** glibc detected *** ./foo: double free or corruption (fasttop): 0x0000000002299030 ***

编辑:这是一个更新/简化的版本,仍然存在同样的问题(仅限测试 2);这不会导致段错误,因为它没有使用指针,但仍会循环两次:

map<int, int> newMap;
newMap[13] = 1340;
cout << "test 2:" << endl;
for(map<int, int>::reverse_iterator it=newMap.rbegin();it!=newMap.rend();){
  cout << "next iteration" << endl;
  int index = it->first;
  int value = it->second;
  it++;
  newMap.erase(index);
}

【问题讨论】:

  • 取消引用 end()rend() 是 UB,因为它们代表 past-the-end 迭代器。
  • 顺便说一句 newMap[13] = new int(1340); 你确定吗?
  • 这解释了测试 1,但测试 2 呢?我在最后添加了一个简化的例子
  • @Jean-FrançoisFabre:是的,我的意思是指向单个 int,但这不是问题的重点,所以我将其修改为值而不是指针。
  • 测试 2:不确定是否可以在迭代时修改地图,无论是否反转。

标签: c++ iterator segmentation-fault


【解决方案1】:

在测试 1 中,您将取消引用过去的迭代器。正如 ArchbishopOfBanterbury 在 cmets 中提到的,其结果是不确定的。

在测试 2 中,您通过擦除 it.base() 指向的元素来使 it 无效。 std::reverse_iterator 拥有一个指向下一个元素的迭代器(所以newMap.rbegin() 拥有一个等于newMap.end() 的迭代器,newMap.rend() 拥有一个等于newMap.begin() 的迭代器)。

当您增加it 时,它变为等于newMap.rend(),这意味着it.base() 等于newMap.begin()。然后删除it.base() 引用的元素,这会使it.base() 无效,从而也使it 无效。由于 it 现在无效,因此无法将其与 newMap.rend() 进行比较。

【讨论】:

    猜你喜欢
    • 2020-09-05
    • 2020-03-30
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2021-04-05
    相关资源
    最近更新 更多