C和指针 6.5 未初始化和非法的指针

缘起

《C和指针》 6.5

分析

考虑下面一段代码

1
2
int *p; // 未初始化
*p = 12; // 注意,根据5.3节,*p是一个合法的左值表达式哦~

这会造成什么状况呢?

首先,如果p是静态变量的话,则在程序加载进内存但是尚未运行之前就会被唯一初始化一次为0(参见3.7节笔记). 如果是自动变量的话,它根本不会被初始化. 但是不论哪种情况,声明一个指向整型的指针都不会导致存储整型变量的内存空间被创建.

如果p中的内容是一个非法的地址. 则*p赋值为12就会出错,程序会终止. 在UNIX系统上,这种错误称为段违例(segment violation)或者内存错误(memory fault)——它提示程序试图访问一个并未分配给它的内存位置. 而在Windows系统中,通过未初始化指针进行间接访问是一般保护性异常(general protection exception)的根源之一.

对那些要求整型数据必须要存储在特定边界范围的机器而言,如果数据存储在错误的边界上的话,那么对这个地址进行访问的话将产生总线错误(bus error).

其实更为严重的错误是如果 p中的地址是合法的地址的话(即恰好在os为程序分配的内存中的话),则出的错就更难排查. 所以我们在使用指针进行间接访问的时候一定要注意指针已经被初始化.