zoukankan      html  css  js  c++  java
  • 每天学点GDB 8

    使用GDB来进行STL容器的调试

    现代C++中STL使用的越来越普遍,较之其它类型,stl容器类的调试显得复杂度更好。本篇以map为例说明如何利用gdb来遍历map中的各成员变量。

    源码如下

    #include <map>
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int arg, char** argv) {
      map<int, string> mapExample;
      mapExample.insert(pair<int,string>(1,"demo_one"));
      mapExample.insert(pair<int,string>(2,"demo_two"));
      mapExample.insert(pair<int,string>(3,"demo_three"));
      map<int,string>::iterator iter;
      for ( iter = mapExample.begin();iter!=mapExample.end();iter++) {
        cout<<iter->second<<endl;
      }
      return 0;
    }

    编译运行

    g++ -o demo -g stl_test.cpp

    运行

    gdb ./demo
    br 14
    r

    显示mapExample容器中的各个元素

    p mapExample
    $1 = std::map with 3 elements = {[1] = "demo_one", [2] = "demo_two", [3] = "demo_three"}

    如果想要知道每个element的所在的内存区域,需要先得到stl map的类型。

    ptype mapExample

    显示如下,成员函数部分略去

    type = class std::map<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<int>, std::allocator<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > [with _Key = int, 
             _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Compare = std::less<int>, 
             _Alloc = std::allocator<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >] {
      private:
        _Rep_type _M_t;

    至此关键性成员变量显示即_M_t

    顺着这条思路继续往下,查看_M_t的结构定义

    p mapExample._M_t

    结果显示出stl map实现使用了红黑二叉树rb-tree

      _M_impl = {
        <std::allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {
          <__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >> = {<No data fields>}, <No data fields>}, 
        members of std::_Rb_tree<int, std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<int>, std::allocator<std::pair<int const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_Rb_tree_impl<std::less<int>, false>: 
        _M_key_compare = {
          <std::binary_function<int, int, bool>> = {<No data fields>}, <No data fields>}, 
        _M_header = {
          _M_color = std::_S_red, 
          _M_parent = 0x6040b0, 
          _M_left = 0x604040, 
          _M_right = 0x604120
        }, 
        _M_node_count = 3
      }
    }

    至此,事情变的简单了,利用_M_left和_M_right就可以遍历各个二叉树结点了。

    手工方式作一次不会觉着很累,但次次都手工查看会觉着不厌其烦。幸运的是,早有人已经提供了自动化的脚本。具体链接如下

    https://gist.github.com/skyscribe/3978082

    使用方法是将上述链接中的内容保存到~/.gdbinit中,如果没有.gdbinit就手工创建一个,该文件在gdb每次启动时会被最先读入。

    有了上述脚本,就可以用plist, pmap, pvector来遍历stl容器了。

  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/hseagle/p/3053628.html
Copyright © 2011-2022 走看看