Skip to content

区分一些概念

1、变量的值(内容)和变量的地址

2、变量名与地址

变量名的实质

变量名实际上是一个符号地址,在对程序编译连接时由系统给每一个变量名分配一个内存地址。在程序中从变量中取值,实际上是通过变量名找到相应的内存地址,从其存储单元中读取数据。

变量名(Variable Name): 编译器的 符号表(Symbol Table) 中的一个条目,包含名称、类型、作用域、地址等信息。

  • 关键细节
    • 名称修饰(Name Mangling):C++ 中为支持重载,编译器会修改函数/变量名(如 _Z3fooi)。
    • 作用域解析:编译器通过符号表区分局部变量与全局变量(如 ::a vs a)。
    • 调试符号:编译时若保留调试信息(如 -g 选项),变量名会被嵌入二进制文件供调试器使用。

地址(Address): 一个无符号整数,通常为 CPU 字长

  • 关键细节
    • 虚拟地址:程序看到的是操作系统提供的虚拟地址,由 MMU(内存管理单元)转换为物理地址。
    • 地址空间布局随机化(ASLR):现代系统随机化进程地址空间以提高安全性。
    • 空指针(NULL):通常定义为 (void*)0,访问它会导致段错误(Segmentation Fault)。

3、指针

指针变量

指针也是变量,存储的是地址,指向该地址

c
int   a = 112, b = -1;
float c = 3.14;
int   *d = &a;
float *e = &c;
地址100104108112116
变量名abcde
112-13.14100108

间接访问

通过一个指针访问他所指向的地址的过程称为间接访问解引用指针: 使用单目操作符 *

c
int   f = *d;

未初始化和非法的指针

一个极为常见的错误:

c
int *a;
...
*a = 12;

无法预测 12 会存储在哪个地方, 声明一个指向整型的指针不会“创建”用于储存整型的内存空间。 一般情况,会指向一个非法地址: 在UNIX上会导致“内存错误”(memory fault) 在Windows上会导致“保护性异常”(general protection exception) 最严重的情况,可能指向了一个合法的地址: 位于那个位置的值被修改,这种错误难以捕捉,导致严重后果。