1. 项目概述:为什么指针与字符串是C语言的核心痛点
指针和字符串的关系,堪称C语言学习路上的"死亡交叉路口"。我见过太多学生在学到char*时彻底崩溃——明明单个字符'a'打印正常,为什么换成字符串就出现乱码?为什么strcpy用着用着程序就崩溃了?这些问题的根源在于没有真正理解内存模型。
这个教程将用x86_64架构下的Linux系统为例,带你看清char*背后的内存布局。我们会用GDB调试器实时观察内存变化,配合objdump反汇编,把抽象的概念变成可视化的内存操作。比如当你声明char *str = "hello"时,这个字符串常量实际存放在ELF文件的.rodata段,而指针变量str本身则在栈上占用8个字节(64位系统)。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 内存模型:从二进制层面理解字符串存储
2.1 字符串常量的存储位置
在Linux环境下编译以下代码:
c复制#include <stdio.h>
int main() {
char *str = "hello";
puts(str);
return 0;
}
使用objdump -s -j .rodata ./a.out查看可执行文件,你会看到类似输出:
code复制Contents of section .rodata:
2000 01000200 68656c6c 6f00 ....hello.
这里的"hello"确实被存放在只读数据段。而通过size ./a.out命令可以看到各内存段的大小分布。
2.2 指针变量的内存表示
在GDB中调试时,使用x/8xb &str查看指针变量所在内存:
code复制(gdb) x/8xb &str
0x7fffffffe3f0: 0x00 0x20 0x00 0x00 0x00 0x00 0x00 0x00
这表示str指针的值是0x2000(小端序),正好指向.rodata段的字符串地址。
关键提示:在x86架构下,指针宽度随系统变化。32位系统是4字节,64位系统是8字节。可以用
sizeof(char*)验证。
