每天学点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容器了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值