最准判断空指针的方式是用gdb的p命令打印指针值,若输出0x0、nullptr或null即为空,否则为非空;段错误后应先bt定位崩溃行,再p指针验证,并可结合info registers交叉确认。

直接用 p 命令打印指针值,看输出是不是 0x0 或 nullptr 或 NULL —— 这是最准、最常用的判断方式。
用 p 查看指针值时怎么看是空
在 GDB 中暂停后(比如段错误停在崩溃行),执行 p ptr(把 ptr 换成你的指针名):
- 如果输出类似
$1 = 0x0、$1 = (int *) 0x0或$1 = nullptr,说明是空指针 - 如果输出是
$1 = (int *) 0x7fffffffeabc这类非零地址,就不是空 - 注意:C 里常定义为
NULL,C++ 里更倾向nullptr,但底层都是 0,GDB 显示可能随编译器和调试信息完整度略有差异 - 别只信变量名——有些指针变量名看着像
head或cur,实际早已被赋成NULL,必须实打实p一下才作数
段错误后怎么快速确认是不是空指针解引用
程序因 SIGSEGV 崩溃并生成 core dump 后,用 gdb ./a.out ./core 加载,然后:
- 先运行
bt看崩溃点在哪一行(比如停在*p = 10;) - 再用
p p(假设指针叫p)确认值;如果确实是0x0,基本可断定是空指针解引用 - 顺手用
info registers看x0(ARM64)或rax(x86_64)寄存器值,也能交叉验证是否为 0 —— 某些内核或汇编级调试中这比p更可靠 - 如果指针是结构体成员(如
cur_gdev->status崩溃),先p cur_gdev,再p *cur_gdev,避免跳过一级就误判
为什么不能只靠代码逻辑“觉得”它不为空
很多崩溃发生在指针本该被初始化,但实际没走到那步:
- 分支未覆盖:比如
if (init_ok) { p = malloc(...); },但init_ok是 false,p保持NULL - 多线程竞态:一个线程刚把指针置为
NULL,另一个线程还没来得及检查就直接用了 - 内存破坏:其它地方越界写,把指针变量所在内存给改成了 0
- GDB 的
p是唯一反映“此刻真实内存值”的手段;光看源码或注释,不如看寄存器和内存
真正麻烦的不是识别空指针,而是它为什么是空——是漏初始化?路径没走通?还是被意外清零?p 只回答“是不是”,下一步得靠 bt、frame、list 和上下文代码一起推。











