程序中对象和变量的引用是如何工作的?

How does the referencing of objects and variables in programs work?

免责声明:我不是一个很有经验的人,很多问题可能看起来很愚蠢或措辞不当。

我听说过栈和堆,也读过一些,但还有一些我不太明白的地方:

How does a program find empty memory to store new variables/objects in physical memory.

物理内存由 OS 管理,它知道内存的哪些部分被进程使用,哪些部分是空闲的。当它需要内存时,程序会要求操作系统使用部分内存。如果此内存用于堆,则需要额外的操作。操作系统通过称为页面的固定大小的块来提供内存。由于一个页面是 4kbytes,如果用户 malloc 有一些字节,则需要优化内存使用,了解页面的哪些部分被使用或可用,并在连续 malloc 之后监视页面内容] 和 free。有特定的数据结构来描述使用的 space 和算法来查找 space,同时避免碎片化。

How does a program know where an object starts and where an object ends in memory. With number variables I can imagine there is a few extra information provided in memory that show the porgram how many bits the variable occupies, but correct me if I'm wrong

程序知道每个变量的地址(即开始)。对于全局或静态变量,它由链接器在将变量放入内存时生成。对于局部变量,处理器可以在给定堆栈位置的情况下对其进行计算。对于分配的变量,它在分配内存时存储在另一个变量(指针)中。关于结束,这取决于变量的类型。对于已知类型(如 int)或已知类型的组合(如 structs),它可以在编译时计算。在其他情况下,程序无法知道实体大小。例如,像 int * a 这样的声明可能描述了一个数组,但程序无法知道数组的大小。程序员必须跟踪此信息,例如将数组中元素的数量写入另一个变量。

This is similar to my first question, but: when a variable has a value representd only by zeros, how does the program not confuse that with free memory.

程序从不查看内存以了解它是否空闲。它通过其他方式管理(参见问题 1)。

Does the object value null mean that the address of an object is a bunch of 0's or does the object point to litterally nothing? And if so, how is the "reference" stored to assign it an address later on?

地址永远不会是一串零,除了内存地址“0”。它是设置为零的内容。实际上,不可能读取或写入地址 0。它会生成 "bus error" 异常(也许您已经遇到过)。指向零地址与 "pointing to litterally nothing" 完全相同,如果在程序中遇到,则会产生错误。这些变量保存其他变量(指针)的地址。所以指针的地址是明确定义的。 was 可能未定义它所指向的内容。它可以通过为指针分配一些东西来修改(例如 malloc 返回的内容或另一个 var 的地址)。

How does a program find empty memory to store new variables/objects in physical memory.

现代操作系统使用逻辑地址转换。一个进程看到一系列逻辑地址——它的地址space。系统硬件将地址范围分成页。页面的大小取决于系统并且通常是可配置的。操作系统管理将逻辑页映射到相同大小的物理页框的页表。

地址space被划分为系统space,所有进程共享的页面范围,以及用户space,通常对每个进程都是唯一的.

在用户和系统 spaces 内,页面可能有效或无效。无效页面尚未映射到进程地址 space。大多数页面可能无效。

内存总是从操作系统映像页面分配。操作系统将提供系统服务,将无效页面转换为有效页面,并映射到物理内存。为了映射页面,操作系统需要找到(或应用程序需要指定)无效页面范围,然后必须分配物理页面框架以映射到这些页面。请注意,物理页框不必连续映射到逻辑页。

你提到栈和堆。栈和堆只是内存。操作系统无法判断内存是栈、堆还是其他东西。用于内存分配的用户模式库(例如那些实现 malloc/free 的库)在页面中分配内存以创建堆。使此内存成为堆的唯一原因是有一个堆管理器控制它。然后堆管理器可以从分配给堆的页面中分配更小的内存块。

堆栈更简单。它只是一个连续的页面范围。通常,创建线程或进程的操作系统服务会为堆栈分配一定范围的页面,并将硬件堆栈指针寄存器分配给堆栈范围的高端。

How does a program know where an object starts and where an object ends in memory. With number variables I can imagine there is a few extra information provided in memory that show the porgram how many bits the variable occupies, but correct me if I'm wrong.

这取决于程序是如何创建的,对象是如何在内存中创建的。对于类型化语言,链接器将变量绑定到地址。链接器还生成用于将这些地址映射到地址 space 的指令。对于 stack/auto 变量,编译器从指向堆栈的指针生成偏移量。当调用 function/subroutine 时,编译器会生成代码来分配过程所需的内存,只需从堆栈指针中减去即可。只需将该值添加回堆栈指针即可释放内存。

对于无类型语言,例如汇编语言或 Bliss,程序员必须跟踪每个位置的类型。当内存是动态的时,程序员还必须跟踪类型。大多数编程语言通过使用类型指针来帮助解决这个问题。

This is similar to my first question, but: when a variable has a value representd only by zeros, how does the program not confuse that with free memory.

可用内存无效。访问空闲内存导致硬件异常。

Does the object value null mean that the address of an object is a bunch of 0's or does the object point to litterally nothing? And if so, how is the "reference" stored to assign it an address later on?

链接器定义程序用户地址的初始状态space。大多数链接器不映射第一页(甚至不止一页)。该页面无效。正如您所说,这意味着空指针绝对没有引用任何内容。如果您尝试取消引用空指针,您通常会遇到某种访问冲突异常

大多数操作系统将允许用户映射第一页。一些链接器将允许用户覆盖默认设置并映射第一页。这并不常见,因为它使检测内存错误变得困难。