C ++ std :: set插入无效读取

时间:2017-02-26 12:51:42

标签: c++ set containers std valgrind

我正在用C ++编写服务器。我使用std :: set容器来保存一个访问所有客户端内存对象的指针。我使用valgrind来检查我是否没有造成任何内存泄漏。我第一次使用套装时读取的内容无效。我写了一个代码示例来解释我的问题。

 $('.glyphicon-th').click(function() {
$(".datepicker").focus();
 });

我用这些标志编译并用valgrind启动我的程序。

#include <iostream>
#include <set>

using namespace std;

int main() {
  set<int> s;

  s.insert(1);
  s.insert(2);
  s.insert(3);

  for (auto it = s.begin(); it != s.end(); it++) {
    cout << "Data:" << *it << endl;
    s.erase(it);
  }

  return 0;
}

此代码产生&#34;无效读取大小为8&#34;到std :: _ Rb_tree_increment(std :: _ Rb_tree_node_base const *)(在/ usr / lib / x86_64-linux-gnu / libstdc ++。so.6.0.21中)

那不是来自我的代码所以我可以解决这个问题吗?

对不起我的英语,我正在学习......

2 个答案:

答案 0 :(得分:3)

调用s.erase(it)后,迭代器it不再有效。对迭代器的任何引用(例如it++中的引用都是未定义的行为。

it调用it++的调用中,似乎递增了std::_Rb_tree_increment,此时调用处于无效状态。 Valgrind检测到这种情况,并报告无效的读数。

答案 1 :(得分:3)

擦除后,

it无效,但erase在最后一个擦除元素后返回一个迭代器,因此您可以将循环更改为

for (auto it = s.begin(); it != s.end();) {
    cout << "Data:" << *it << endl;
    it = s.erase(it);
}