gdb vector及思考

开发的时候,遇到一个问题vector中的对象在使用的时候被析构了,看代码无法理解,没啥说的,gdb跟踪。但是print vector变量智能打印地址,怎么展示对象的内容呢?

(gdb) p second
$2 = {<std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >> = {
    _M_impl = {<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<__gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>}, <std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_Vector_impl_data> = {_M_start = 0x618c70, _M_finish = 0x618cb0, _M_end_of_storage = 0x618cb0}, <No data fields>}}, <No data fields>}

网上查阅,下帖,作者自己写的工具可以实现打印。gdb中 source这个工具文件,就可以使用工具。
http://blog.chinaunix.net/uid-25006789-id-3945673.html

分析脚本工具,核心脚本如下:

        set $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_start
        set $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_start
        set $size_max = $size - 1
        set $i = 0
        while $i < $size
            printf "elem[%u]: ", $i
            p *($arg0._M_impl._M_start + $i)
            set $i++
        end
## 尝试,确实可以
(gdb) p *(second._M_impl->_M_start)
$14 = {
  static npos = 18446744073709551615,
  _M_dataplus = {
    <std::allocator<char>> = {
      <__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
    members of std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider:
    _M_p = 0x618c80 "bcd"
  },
  _M_string_length = 3,
  {
    _M_local_buf = "bcd\000\377\177\000\000 \177\335\367\377\177\000",
    _M_allocated_capacity = 140733199967074
  }
}
(gdb) p *(second._M_impl->_M_start+1)
$15 = {
  static npos = 18446744073709551615,
  _M_dataplus = {
    <std::allocator<char>> = {
      <__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
    members of std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider:
    _M_p = 0x618ca0 "cde"
  },
  _M_string_length = 3,
  {
    _M_local_buf = "cde\000\000\000\000\000I/\025\367\377\177\000",
    _M_allocated_capacity = 6644835
  }
}

这不就是带类型的指针 或者数组概念嘛。感觉之前对数组指针没有理解到位,看stl源码,虽然_M_impl._M_finish 、_M_impl._M_start是两个带类型的指针,编译器可以根据类型计算出对象数量。

用char和int写demo验证,代码及结果如下

#include<iostream>
using namespace std;
#include<vector>
#include <cstring>

int main()
{
        char test2[] = {"abcdefabcdefabcdef"};
        std::cout << "char* type test2 len: " << strlen(test2) << std::endl;
        char* test2_end = test2+strlen(test2);
        std::cout << "test2 size: " <<  (test2_end - test2) << std::endl;

        int *test3 = (int*)test2;
        int* test3_end = test3+((test2_end - test2)/4==0?(test2_end - test2)/4:(test2_end - test2)/4+1 );
        std::cout << "test3 size: " <<  (test3_end - test3) << std::endl;

        getchar();

        return 0;

}

char* type test2 len: 18
test2 size: 18   // 字符18个
test3 size: 5    // int类型数量5个


(gdb) p test3
$1 = (int *) 0x7fffffffe2e0
(gdb) p test3_end
$2 = (int *) 0x7fffffffe2f4
(gdb) p 0x7fffffffe2f4 -0x7fffffffe2e0
$3 = 20
(gdb) p test3_end -test3
$4 = 5
(gdb)

总结下,vector可以用如下方法打印

(gdb) p second
$2 = {<std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >> = {
    _M_impl = {<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<__gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>}, <std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_Vector_impl_data> = {_M_start = 0x618c70, _M_finish = 0x618cb0, _M_end_of_storage = 0x618cb0}, <No data fields>}}, <No data fields>}
(gdb) p second._M_impl->_M_start
$3 = (std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::pointer) 0x618c70
(gdb) p *(std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::pointer) 0x618c70
$4 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x618c80 "bcd"}, _M_string_length = 3, {
    _M_local_buf = "bcd\000\377\177\000\000\000\252\260\367\377\177\000", _M_allocated_capacity = 140733199967074}}
(gdb) p *(second._M_impl->_M_start)
$5 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x618c80 "bcd"}, _M_string_length = 3, {
    _M_local_buf = "bcd\000\377\177\000\000\000\252\260\367\377\177\000", _M_allocated_capacity = 140733199967074}}
(gdb)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 16,691评论 0 26
  • Bookmarks 书签栏 入职 华为新员工小百科(刷新时间202003023) - 人才供应知多少 - 3MS知...
    Btrace阅读 5,493评论 0 0
  • 简述:    一直希望有个机会可以好好研究一下android手机的多主题功能,借此机会将自己所能分析到的内容记录...
    大天使之剑阅读 5,927评论 0 6
  • J2SE 基础 八种基本数据类型的大小,以及他们的封装类。 八种基本数据类型,int ,double ,long ...
    第四风111阅读 4,999评论 3 23
  • J2SE 基础 八种基本数据类型的大小,以及他们的封装类。 八种基本数据类型,int ,double ,long ...
    镜中无我阅读 1,189评论 0 0

友情链接更多精彩内容