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容器了。

  • 相关阅读:
    cpp:博文_注意
    Algs4-1.2(非习题)String
    Algs4-1.2(非习题)几何对象中的一个2D用例
    Algs4-1.2.19字符串解析
    Algs4-1.2.18累加器的方差
    Algs4-1.2.17有理数实现的健壮性
    Algs4-1.2.16有理数
    Algs4-1.2.15基于String的split()的方法实现In中的静态方法readInts()
    Algs4-1.2.13实现Transaction类型
    Algs4-1.2.14实现Transaction中的equals()方法
  • 原文地址:https://www.cnblogs.com/hseagle/p/3053628.html
Copyright © 2011-2022 走看看