You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:37:39