我知道如果在 C 中声明了一个指针(而不是初始化),它将指向一个可以包含任何内容的“随机”内存地址。
它实际上指向的位置是如何确定的?大概它不是真正随机的,因为这将是低效且不合逻辑的。
如果这个指针是在所有函数之外定义的(或 is static
),它将在获得控制权NULL
之前被初始化。main()
如果这个指针是通过在堆中创建的malloc(sizeof(sometype*))
,它将包含恰好在其位置的任何内容。它可以是来自先前分配和释放的内存缓冲区的数据。或者它可以是一些旧的控制信息,malloc()
用于free()
管理空闲和分配块的列表。或者,如果操作系统(如果有)没有清除程序的内存,或者如果它的内存分配系统调用返回未初始化的内存,那么它可能是垃圾,因此这些可能包含来自以前运行的程序的代码/数据,或者只是你的 RAM 芯片在系统已开机。
如果这个指针是一个函数的本地指针(并且不是static
),它将包含任何已经在堆栈中的位置。或者,如果一个 CPU 寄存器被分配给这个指针而不是一个内存单元,它将包含前面的指令在这个寄存器中留下的任何值。
所以,它不会是完全随机的,但你很少在这里完全控制。
未初始化是未定义的。一般来说,当指针被分配时,内存空间并没有被清除,所以现在包含的内存都是指针。它是随机的,但在操作中不会更改内存位置的意义上,它也是有效的。
http://en.wikipedia.org/wiki/Uninitialized_variable
诸如 C 之类的语言将堆栈空间用于变量,为子程序分配的变量集合称为堆栈帧。虽然计算机会为堆栈帧留出适当数量的空间,但它通常只是通过调整堆栈指针的值来做到这一点,并且不会将内存本身设置为任何新状态(通常是出于效率考虑)。因此,当时该内存的任何内容都将显示为占据这些地址的变量的初始值。
虽然我想这是特定于实现的。
此外,您可能应该始终初始化您的指针,请参阅如何检查无效指针?以及第一个答案中给出的链接:-
就 C 标准而言,未初始化的指针并不指向任何地方。取消引用它是非法的。因此,原则上不可能观察其目标,因此目标根本不存在于所有意图和目的。
如果你想要一个陈词滥调的类比,要求一个未初始化的指针的值就像要求最小的正实数的值,或者 π 的最后一位的值。
(推论是只有 Chuck Norris 可以取消引用未初始化的指针。)
它是实现特定/未定义的行为。指针可能被自动初始化为 NULL ......或者它只是当时内存中的任何值。
指针是内存中的一个地址,它指向内存中的另一个地址。它没有被初始化的事实并不意味着指针本身没有地址,它只意味着它所指向的东西的地址是未知的。因此,编译器默认将其初始化为 NULL,或者地址是当时指针变量空间中内存中的任何内容。
在很大程度上,它就像您进入课堂时未擦除的白板。如果你在棋盘的一部分上画了一个盒子,但没有擦掉盒子里的东西,那么盒子里有什么?
它是以前留下的任何东西。
同样,如果为指针分配空间但不擦除空间,那么空间中有什么?
数据可能来自程序的早期部分或在程序的任何正常部分(例如main
函数)开始运行之前运行的特殊代码。(特殊代码可能会加载和链接某些库、设置堆栈以及准备 C 程序所需的环境。)在嵌入式系统上,而不是典型的多用户系统上,数据可能会从以前的进程中遗留下来。很可能,之前使用空间的目的不是指针,因此当解释为指针时,其中的值没有意义。它作为指针的值可能指向某个地方,但没有任何意义。
但是,您不能依赖于此。当您使用具有自动存储持续时间的未初始化对象时,C 标准没有定义行为。在许多 C 实现中,未初始化的指针将仅包含剩余数据。但是,在某些 C 实现中,系统可能会检测到您正在使用未初始化的对象并导致您的程序崩溃。(其他行为也是可能的。)