【发布时间】:2016-01-31 06:43:16
【问题描述】:
让我们将这段 C++ 代码视为一个粗略的示例。
int *A = new int [5];
int *B = new int [5];
int *C = new int [5];
delete []A;
delete []C;
int *D = new int [10];
显然,任何机器都可以处理这种情况,而不会出现缓冲区溢出或内存泄漏的任何问题。然而,让我们想象长度乘以一百万甚至更大的数字。据我所知,所有数组元素的地址(至少是虚拟地址)都是连续的。所以每当我创建一个数组时,我可以确定它们是虚拟内存中的连续块,如果我有指向第一个元素的指针,我可以执行指针算术来访问第 n 个元素。下图说明了我的问题(为简单起见,忽略了表示数组末尾的寄存器)。
在堆中分配 A、B、C 之后,我们释放 A 和 C 并获得两个长度为 5 的空闲内存块(用绿点标记)。当我想分配一个长度为 10 的数组时会发生什么?我认为有3种可能的情况。
-
我会因为没有连续的 10 长内存块而得到 bad_alloc 异常。
-
程序会自动将数组 B 重新分配到堆的开头,并将其余未使用的内存连接在一起。
-
数组 D 将被拆分为 2 部分并且不连续存储,导致数组的第 n 个元素的访问时间不恒定(如果拆分多于 2 个,则它开始类似于链表而不是数组) .
其中哪一个是最可能的答案,还是我没有考虑其他可能的情况?
【问题讨论】:
-
这非常依赖于操作系统。
-
@JamesAdkison 是的,假设我们只有 15 个堆内存寄存器。否则这个问题将毫无意义。
-
它还忽略了程序使用虚拟内存而不是物理硬件内存这一事实。这更像是一个理论问题。理论上的答案是期望
new或malloc在后续请求大于可用内存时返回NULL。 -
您的标题非常笼统。请让它识别问题。
-
@n.m.所以你说的内存分配和这样的转移在 Arduino 上和在 Windows 上是一样的吗?我觉得像 RTEMS 这样的 RTOS 在遇到碎片内存时肯定会与 OSX 表现不同(即 RTEMS 什么都不做 OSX 可能会做一些事情)...
标签: c++ arrays memory memory-management