watch中直接输入arr只显示地址或首行,因gdb将int* arr视为指针的指针,arr@n仅展开n个int地址而非二维结构;需用x命令查静态数组或分步解引用查动态数组。

Watch 里直接输 arr 为什么只看到地址或首行?
GDB 把 int** arr 当作“指向指针的指针”,arr 本身只是个地址,arr@N 只会展开 N 个 int*(即 N 个内存地址),不是 N 行数据。比如 arr@3 显示三个地址,而非每行 5 个 int 的二维结构。
真正想看逻辑上的“行×列”布局,不能靠 Watch 直接求值;它不理解多维语义,也不支持运行时下标(arr[i][j] 会报 <optimized out></optimized> 或语法错误)。
用 x 命令查连续二维数组(如 int arr[3][4])
静态/栈上二维数组是连续内存块,适合用 x 命令按行主序一次性展开:
-
x/12dw &arr:查看全部 12 个int,按十进制显示 -
x/3xw &arr:每行 4 个int,共 3 行,用w(word=4 字节)单位 +x(十六进制)更易对齐 - 若要验证内存是否真连续,可比对
&arr[0][0]和&arr[1][0]地址差是否等于sizeof(int) * 4
查动态二维数组(如 int** matrix)必须分步解引用
动态分配的 int** 是指针数组,每行首地址独立,GDB 无法自动拼出二维视图。必须手动构造表达式:
- 看第 0 行全部元素:
*(matrix + 0)@5或*matrix@5 - 看第 1 行:
*(matrix + 1)@5 - 看第 i 行(i 是变量):先
print i查值,再手输*(matrix + <em>具体数字</em>)@5 - 若行长度不一致(ragged array),每行都要单独确认长度,再拼
@N
三维及以上优先用 @ 链式切片,但尺寸顺序和星号数必须严格匹配
例如 int*** cube 存储 2×3×4 数据:
- 正确:
***cube@2@3@4(先解三层指针,再按维度顺序切片) - 等效但更安全:
*(int(*)[3][4])cube@2(强转为“含 2 个int[3][4]元素的数组”) - 错误:
**cube@2@3@4(少一个*)、***cube@4@3@2(尺寸顺序反了) - 所有尺寸必须是编译期常量;若来自变量(如
n),先在 Debug Console 执行print n查值,再手动替换
真正想确认字节级布局(比如 padding、越界写、字段偏移),别依赖 Watch 或 p,用 Memory 视图:右键变量 → “Copy Address”,粘贴进去,设 Display Format 为 Hex、Width 为 Byte,对照 offsetof 和 sizeof 手动定位——这是唯一能看见物理内存真实排布的方式。











