当您分配内存时,使用new double[26]
,系统将为您的应用程序提供一块内存,其空间至少为 26 x sizeof(double)。分配函数确实会将数字 26(或可以以其他方式取回数字 26 的东西)存储在它的元数据内的某个位置,用于内存分配。
但是,调试器无法“弄清楚”元素的数量是 26,它只知道这是指向某些double
值的指针。当您要求看起来超过 26 岁时,您就处于“未定义行为”领域——任何事情都可能发生并且可能会发生。包括它看起来像您“预期”的那样完美(也就是说,内存是可读的并且包含可以显示为“double”的值。然后,当您到达元素 224 时,调试器无法读取任何内存更长的时间(因为操作系统已将其标记为“不可用”)。那是它停止的时间。它可能是 50000000 [在这种情况下,您可能需要几个小时才能到达这里并提出这个问题......]
对。为简单起见,假设我们有一台具有 100KB RAM 的计算机。处理器分配用于什么目的的内存的方式是一次 4KB 的页面。所以我们有 25 页。其中一些页面是您的“堆”(其中new
得到它的记忆)。一个内存分配获得了这样一个 4KB 页面的一部分。假设我们的内存恰好位于第 18 - 18 * 4096 = 73728 到 77823 页。第 19 页被标记为“未使用”。我们在这个页面中的分配是 168 字节(前 168 字节用于其他用途) - 所以我们的地址是 73896,现在,我们有 26 * 8 = 208 字节,所以“下一个可用字节”是 73728+376 = 74104这页纸。所以,y[0] 的地址是 73896,我们每个 double 占用 8 个字节。当我们到达 74104(索引 26,在我们分配的内存之外)时,我们仍然在第 18 页,根据处理器/操作系统,它仍然“可用”。在处理器说“你不能去那里”之前,我们必须一直走到 77824。74104 - 77824 = 3720 字节,或 465* sizeof(double)。但是我们正在使用我们被告知不要使用的内存。所以,
我希望这可以很好地解释它。
它是 4KB 的原因是,如果处理器必须跟踪内存的每一个字节,那么它会占用太多内存来跟踪该字节是否可用。4KB 是“我们检测到何时外出足够长的时间”和“它占用了太多容量”之间的一个很好的折衷。