C++

编译器为什么不把指针初始化为null

Posted by Peinan on September 1, 2019

“前段时间想到一个问题,编译器会把int变量初始为0,而指针却不初始化为null,引起野指针的问题?” - False

Google了一下,纠正了一些错误的认知。

其实这个说法是错的,int型变量不一定会初始化为0,指针变量也不是一定不初始化(C# / Java中的对象 = 指针,同理)。

正确的说法应该是,在静态存储区的变量会被初始化为0,而在堆和栈上的不会。

这么做是为了提高效率,对于存放于静态存储区的全局变量,编译器可以在生成之前就统一对该处内存清零,因此在运行时没有额外的开销。

而对于需要在运行时申请的内存,如堆和栈上的内存,如果将其清0,需要一步额外的操作,为了提高效率,故不清零。

编译器对指针和数值是平等对待的,不会存在差异性。

另外再补充一下程序的内存分布:

栈 - 由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作类似数据结构中的栈。

堆 - 用于程序动态申请分配和释放空间。正常情况下,程序员申请的空间在使用结束后应该释放,若程序员没有释放空间,则程序结束时系统自动回收。和数据结构中的堆不同。

静态存储区 - 分为DATA段和BSS段。DATA段存放初始化的全局变量和静态变量;BSS段存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中BSS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。

文字常量 - 存放常量字符串。程序结束后由系统释放。

代码 - 存放程序的二进制代码。