在 C 語言中,獲取地址的方法因對象類型而異:普通變量用 &,數組/字符串/函數名本身即地址。本文系統總結各類對象地址獲取方法,並演示 GDB 調試驗證函數地址技巧。
| 對象類型 | 獲取方法 | 示例 | 本質 |
|---|---|---|---|
| 普通變量 | &var | &a | 取地址運算符 |
| 數組 | arr 或 &arr[0] | set | 數組名退化為首元素指針 |
| 字符串字面量 | "str" 或 pStr | pStr | 存儲在只讀數據段的首地址 |
| 字符指針變量 | pStr(值即地址) | pStr | 指針變量本身存地址 |
| 函數 | func 或 &func | show | 函數名即代碼段入口地址 |
| 函數指針 | pFunc(值即地址) | pFunc | 指針變量存函數地址 |
#includeint hello() { printf("hello\n"); return 0; } int show() { printf("show running\n"); return 0; } int main() { int a = 1; int set[3]; char* pStr = "string"; int (*pFunc)() = hello; // 函數指針 printf("address of a: %p\n", (void*)&a); printf("address of set: %p\n", (void*)set); printf("address of string: %p\n", (void*)pStr); printf("address of func*: %p\n", (void*)pFunc); // 通過函數指針 printf("address of show: %p\n", (void*)show); // 直接用函數名 return 0; }
address of a: 0x7ffc12345678 address of set: 0x7ffc12345680 address of string: 0x555555556004 address of func*: 0x555555555149 address of show: 0x555555555162
# 1. 編譯帶調試信息
gcc -g addr_demo.c -o addr_demo
# 2. 進入 GDB
gdb ./addr_demo
# 3. 設置臨時斷點並運行
(gdb) start
Temporary breakpoint 1 at 0x...: file addr_demo.c, line 18.
Starting program: ...
Breakpoint 1, main () at addr_demo.c:18
# 4. 查看函數地址
(gdb) info address hello
Symbol "hello" is a function at address 0x555555555149.
(gdb) info address show
Symbol "show" is a function at address 0x555555555162.
(gdb) info address main
Symbol "main" is a function at address 0x55555555517f.
# 5. 也可打印函數指針值
(gdb) p hello
$1 = {int ()} 0x555555555149
(gdb) p show
$2 = {int ()} 0x555555555162
a、set、pStr、pFunc(高地址向低增長)。"string"(地址較低,通常靠近代碼段)。hello、show、main(最低地址區域)。理解地址分佈對調試棧溢出、緩衝區溢出、函數指針調用極有幫助。
&set vs set:類型不同(int(*)[3] vs int*),但數值相同。&pStr 是指針變量自身的地址(棧上),非字符串地址。show 可直接賦值給函數指針,&show 等價但較少用。熟練掌握各類對象地址獲取方式,是 C 指針編程、調試分析、底層內存操作的基石技能。