0

自操作系统会话开始以来,分配的内存是否保存垃圾值?在我们将其命名为程序运行时会话中的垃圾值之前,它是否具有某种意义?如果是,那为什么?

我需要一些关于 linux 内核编程、设备驱动程序编程的学习材料的建议,并且还想了解计算机设备的实际工作原理。我陷入了诸如“垃圾价值”之类的情况,并且觉得我还必须学习其他东西才能更好地理解编程语言。我正在自学,遇到很多令人困惑的情况。任何建议都会非常有帮助。

4

5 回答 5

4

“垃圾价值”是一个俚语,意思是“我不知道那里有什么价值,或者为什么,因此我不会使用这个价值”。它是“无用的废话”意义上的“垃圾”,有时它也是“别人的剩菜”意义上的“垃圾”。

形式上,C 中未初始化的内存采用“不确定值”。这可能是由 C 实现写在那里的一些特殊值,或者它可能是同一内存的早期用户“遗留”的东西。因此,例如:

  • C 运行时的调试版本可能会用一个引人注目的值填充新分配的内存,因此,如果您在调试器中看到它时您期望自己存储的数据,您可以合理地得出结论,要么忘记初始化它,要么你找错地方了。
  • “正确”操作系统的内核将在第一次分配给进程时覆盖内存,以避免一个进程看到“属于”另一个进程的数据,并且出于安全原因,这些数据不应跨越进程边界泄漏。通常它会用一些已知的值覆盖它,比如 0。
  • 如果您malloc记忆,在其中写一些东西,然后再写free一些malloc记忆,您可能会再次获得相同的记忆,其先前的内容基本上完好无损。但从形式上讲,您新分配的缓冲区仍然是“未初始化的”,即使它恰好与您释放它时的内容相同,因为形式上它是一个全新的字符数组,恰好与旧的具有相同的地址。

在 C 中不使用“不确定值”的一个原因是标准允许它成为“陷阱表示”。当您将某些类型的某些不可能的值加载到寄存器中时,有些机器会注意到,并且您会遇到硬件故障。因此,如果内存先前用于,例如 an int,但随后该值被读取为 a float,那么谁能说剩余的位模式是否代表所谓的“信号 NaN”,这会停止程序?如果您将值作为指针读取并且它与类型不对齐,也会发生同样的情况。甚至整数类型也允许具有“奇偶校验位”,这意味着读取垃圾值int可能具有未定义的行为。在实践中,我认为任何实现实际上都没有陷阱表示int,并且我怀疑如果您只是读取指针值,任何人都会检查未对齐的指针——尽管如果您取消引用它,它们可能会检查。但如果不谨慎,C 程序员就一事无成。

于 2012-08-24T10:25:15.500 回答
2

什么是垃圾价值?

当您在内存位置遇到值并且无法确定这些值应该是什么时,那么这些值对您来说就是垃圾值。即:值为Indeterminate
最常见的是,当您使用变量但未对其进行初始化时,该变量具有 Indeterminate 值并被称为具有垃圾值。请注意,使用 Uninitialized 变量会导致Undefined Behavior,这意味着该程序不是有效的 C/C++ 程序,它可能会显示(字面上)任何行为。

为什么特定值存在于该位置?

今天的大多数操作系统都使用虚拟内存的概念。用户程序看到的内存地址是虚拟内存地址而不是物理地址。虚拟内存的实现将虚拟地址空间划分为页面,即连续的虚拟内存地址块。一旦使用完毕,这些页面通常至少有 4 KB。这些页面没有明确擦除其内容,它们仅被标记为可重用,因此如果未正确初始化,它们仍包含旧内容。

于 2012-08-24T09:58:39.317 回答
0

在典型的操作系统上,您的用户空间应用程序只能看到一定范围的虚拟内存。由内核将此虚拟内存映射到实际的物理内存。

当一个进程请求一块(虚拟)内存时,它最初会保留其中的任何内容——它可能是进程的另一部分之前使用的重用内存,也可能是完全不同的内存进程一直在使用......或者它可能根本没有被触摸过并且处于您打开机器电源时的任何状态。

通常没有人会代表您用零(或任何其他同样任意的值)擦除内存页面,因为没有意义。完全取决于你的应用程序以任何你喜欢的方式使用内存,如果你还是要写它,那么你不在乎它之前有什么。

因此,在 C 中,在未定义行为的痛苦下,根本不允许在写入变量之前读取它。

于 2012-08-24T09:58:39.630 回答
0

如果您声明一个变量而不将其初始化为特定值,则它可能包含一个先前由另一个程序分配的值,该程序已释放该内存,或者它可能只是计算机启动时的随机值( iirc,PC 过去在启动时将所有 RAM 初始化为 0,因为早期版本的 DOS 需要它,但新计算机不再这样做)。例如,您不能假设该值为零。

于 2012-08-24T10:01:31.670 回答
0

垃圾值,例如在 C 中,通常指的是如果您只是保留内存但从不初始化它,它将保存随机值,因为它还没有初始化(C 不会自动为您这样做;它会只是开销,而 C 旨在尽可能少地开销)。内存中的随机值是以前存在的任何东西的剩余物。

这些先前的值保留在那里,因为通常将内存设置为零 - 或任何其他值 - 没有太多用处 - 稍后将再次被覆盖。因为对于一般情况,读取未初始化的内存没有用(除非您想利用可能的安全问题 - 请参阅内存实际归零的特殊情况:内核归零内存?)。

于 2012-08-24T10:05:25.473 回答