如何在GDB中通过shared_ptr打印C++自引用类的字段值
问题描述
我遇到了如下代码,不确定这是否属于自引用类的示例:
#include <iostream> #include <memory> // std::shared_ptr namespace internal { class SomeThing { public: int count = 0; }; } class SomeThing final { public: SomeThing(); ~SomeThing(); void Process( int innum ); private: internal::SomeThing* p; }; SomeThing::SomeThing() : p( new internal::SomeThing() ) { } SomeThing::~SomeThing() { delete p; } void SomeThing::Process( int innum ) { p->count = p->count + innum; } static SomeThing something; static std::shared_ptr<SomeThing> something_ptr{ std::shared_ptr<SomeThing>{}, &something }; int main() { something.Process(3); // something.p->count: error: 'p' is a private member of 'SomeThing' std::cout << "Hello, world!" << std::endl; return 0; }
编译后在GDB中调试时,通过something变量可以轻松打印count字段:
$ g++ -g -std=c++11 -o main main.cpp $ gdb --args ./main ... (gdb) b main Breakpoint 1 at 0xbbb: file main.cpp, line 42. (gdb) r Starting program: /home/runner/e3t9ocha14t/main warning: Error disabling address space randomization: Operation not permitted Breakpoint 1, main () at main.cpp:42 42 something.Process(3); (gdb) p something $1 = {p = 0x561b93a98e70} (gdb) p something->p $2 = (internal::SomeThing *) 0x561b93a98e70 (gdb) p *something->p $3 = {count = 0}
但我无法通过shared_ptr(something_ptr)实现同样的操作,即访问并打印count字段的值。在C语言中可以直接解引用指针,那在C++的shared_ptr场景下该如何操作?
解答
首先,这段代码不属于自引用类,自引用类的核心是类内部持有指向自身类型的指针/智能指针,而这里SomeThing持有的是internal::SomeThing的指针,属于完全不同的类型,和自引用无关。
关于GDB中通过shared_ptr访问内部字段的问题,你只需要先获取智能指针指向的原始对象,再按普通对象的方式操作即可,有两种常用写法:
写法1:通过get()获取原始指针后操作
# 获取shared_ptr指向的原始对象指针 (gdb) p something_ptr.get() $4 = (SomeThing *) 0x561b93a98e60 # 解引用指针并访问内部p成员 (gdb) p (*something_ptr.get())->p $5 = (internal::SomeThing *) 0x561b93a98e70 # 打印最终的count字段 (gdb) p *(*something_ptr.get())->p $6 = {count = 0}
写法2:直接解引用shared_ptr获取对象引用
# 解引用shared_ptr得到对象,再访问p成员 (gdb) p (*something_ptr).p $7 = (internal::SomeThing *) 0x561b93a98e70 # 打印count字段 (gdb) p *(*something_ptr).p $8 = {count = 0}
另外需要注意,你这里的something_ptr使用了空删除器的构造方式,意味着这个智能指针不会管理something的生命周期——这是正确的,因为something是静态变量,会由程序自动销毁,不需要shared_ptr介入。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

