无效的迭代器:第一次使用时如何获取一些调试信息?

Invalid iterators: how to get some debug info on it when the first time it is used?

如果可以从调试器获得更多信息,这将非常有帮助。比如下面的程序

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> x = {1, 2, 3};

    for (std::vector<int>::iterator it = x.begin(); it != x.end(); ++ it)
    {
        x.erase(it);
        std::cout << *it << std::endl;
    }
}

如果 gdbvalgrind 或其他调试方法可以在首次使用 *it 时显示无效的迭代器消息,而无需手动检查问题,那就太好了。

It would be great if gdb or valgrind or other debugging method can show an invalid iterator message when *it is first used

您可以使用 libstdc++ 调试模式(由 -D_GLIBCXX_DEBUG 启用)来帮助解决此类错误。示例:

g++ -std=c++11 -g -D_GLIBCXX_DEBUG t.cc && gdb -q ./a.out

(gdb) r
Starting program: /tmp/a.out
/usr/include/c++/4.8/debug/safe_iterator.h:264:error: attempt to
    dereference a singular iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fffffffe1d0 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPiNSt9__cxx19986vectorIiSaIiEEEEENSt7__debug6vectorIiS6_EEEE (mutable iterator);
  state = singular;
  references sequence with type `NSt7__debug6vectorIiSaIiEEE' @ 0x0x7fffffffe1d0
}

Program received signal SIGABRT, Aborted.
0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff75350d8 in __GI_abort () at abort.c:89
#2  0x00007ffff7b85fe5 in __gnu_debug::_Error_formatter::_M_error (this=0x7fffffffdf90) at ../../../../../src/libstdc++-v3/src/c++11/debug.cc:781
#3  0x0000000000402144 in __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > >, std::__debug::vector<int, std::allocator<int> > >::operator* (this=0x7fffffffe1d0) at /usr/include/c++/4.8/debug/safe_iterator.h:262
#4  0x000000000040145c in main () at t.cc:11
(gdb) fr 4
#4  0x000000000040145c in main () at t.cc:11
11          std::cout << *it << std::endl;