多进程操作系统中的垃圾值

时间:2012-08-24 09:52:09

标签: c linux memory-management kernel

自OS会话开始以来,分配的内存是否保留垃圾值?在我们在程序运行时会话中将其命名为垃圾值之前,它是否具有一定的意义?如果是这样,为什么呢?

我需要一些关于Linux内核编程,设备驱动程序编程的学习材料的建议,并且还希望了解计算机设备的实际工作方式。我陷入了“垃圾价值”这样的境地,并且觉得我还要学习其他东西,以便更好地理解编程语言。我正在自己学习并且遇到很多令人困惑的情况。任何建议都会非常有帮助。

5 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:2)

  

什么是垃圾值?

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

  

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

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

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

垃圾值,例如在C中,通常指的是如果你只保留内存,但从不初始化它,它将保留随机值,因为它还没有初始化(C不会自动为你做;它只是开销,和C的设计尽可能少。) 记忆中的随机值是之前的任何遗留物。

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