空指针在C/C++中占有特殊的地址
访问空指针
空指针在C/C++中占有特殊的地址,通常它是用来判断一个指针的有效性的。空指针一般定义为0。现代操作系统都
会保留从0开始的一块内存,至于这块内存有多大,视不同的操作系统而定。一旦程序试图访问这块内存,系统就会触发
一个异常/信号。
操作系统为什么要保留一块内存,而不是仅仅保留一个字节的内存呢?这是因为一般内存管理都是按页进行管理的
,根本就无法单纯保留一个字节,而至少要保留一个页面。保留一块内存也有额外的好处,可以检查诸如p=NULL; p[1]
之类的内存错误。
在一些嵌入式系统中(如ARM7),从0开始的一块内存是用来安放中断向量的,没有MMU的保护,直接访问这块内存
好像并不会引发异常。不过这块内存是代码段的,而不是程序中有效的变量地址,所以用空指针来判断指针的有效性仍
然可行。
引用未初始化的变量
未初始化变量的内容是随机的(有的编译器会在调试版本中把它们初始化为固定值,如0xcc),使用这些数据会造
成不可预料的后果,调试这样的bug也是非常困难的。
对于态度严谨的程度员来说,要防止这类bug出现其实非常容易,只需要在声明变量时记得对它进行初始化就行,这
是一个好的编程习惯,希望大家能够在学习编程中逐渐养成这个习惯。另外我们也要重视编译器的警告信息,一旦发现
引用了未初始化的变量,就要立即修改过来。
在下面这个例子中,全局变量g_count是确定的,因为它在bss段中,已经是自动初始化为0了。临时变量a是没有初
始化的,堆内存str也是没有初始化的。但这个例子有点特殊,由于程序刚运行起来,很多东西都是确定的,因此如果你
想把它们当作随机数的种子是不行的,因为它们还不够随机。
#include
#include
int g_count;
int main(int argc, char* argv[])
{
int a;
char* str = (char*)malloc(100);
return 0;
}
不清楚指针运算
对于一些新手来说,指针常常让他们犯糊涂。
比如,int *p = ...; p+1等于(size_t)p + 1吗?
老手们自然心里清楚,但新手可能就弄不太清了。
事实上, p+n 等于 (size_t)p + n * sizeof(*p)。
指针是C/C++中最有力的武器,功能非常强大,无论是变量指针还是函数指针,都应该掌握得非常熟练。只要有不确
定的地方,就应该马上写个小程序验证一下。如果对每一个细节都了然于胸,可以在编程时省下不少时间。