正如标题所说,我想知道在c ++中,一个新操作分配的内存是否是连续的......
答案 0 :(得分:17)
BYTE* data = new BYTE[size];
在此代码中,无论给出什么大小,返回的内存区域都是连续。如果堆管理器无法分配size
的连续内存,则会失败。
malloc
中的NULL)
程序员总会看到进程地址空间中连续(和是,无限:-)内存的错觉。这就是虚拟内存为程序员提供的内容。
请注意,程序员(除少数嵌入式系统外)总是看到虚拟内存。但是,可以以任意方式在物理存储器中映射实际连续的存储器(以“页面”大小的粒度,通常为4KB)。那个映射,你看不到,而且大多数你不需要理解它(除了非常具体的页面级优化)。
这个怎么样?
BYTE* data1 = new BYTE[size1];
BYTE* data2 = new BYTE[size2];
当然,您无法说出data1
和data2
的相对地址。这通常是不确定的。它取决于堆管理器(例如malloc
,通常new
只是包裹malloc
)策略和当前请求的当前堆状态。
答案 1 :(得分:6)
您的进程的地址空间中分配的内存将是连续的。
这些字节如何映射到物理内存是特定于实现的;如果你分配了一个非常大的内存块,它很可能被映射到物理内存的不同部分。
编辑:由于有人不同意保证字节是连续的,标准说(3.7.3.1):
分配功能尝试分配所请求的存储量。如果成功,它将返回一个存储块的起始地址,其长度以字节为单位应至少与请求的大小一样大。
答案 2 :(得分:4)
案例1: 使用“new”分配数组,如
int* foo = new int[10];
在这种情况下,foo 的每个元素将位于连续的虚拟内存中。
案例2: 非原子地使用连续的“新”操作,如
int* foo = new int;
int* bar = new int;
在这种情况下,永远不能保证在“new”调用之间分配的内存在虚拟内存中是相邻的。
答案 3 :(得分:2)
分配的字节的虚拟地址将是连续的。它们在支持进程地址空间的驻留页面中也是物理连续的。物理页面到进程虚拟空间区域的映射是非常特定于操作系统和平台的,但一般来说,您不能假设在页面上大于或未对齐的物理连续范围。
答案 4 :(得分:1)
如果您的问题意味着“将连续(及时)新的()操作返回相邻的内存块,两者之间没有间隙?”,这位老程序员会非常礼貌地建议您不要依赖它
问题出现的唯一原因是,如果您打算将指针“移出”一个数据对象并“进入”下一个数据对象。这是一个非常糟糕的主意,因为您无法保证地址空间中的下一个对象与前一个对象的类型非常相似。
答案 5 :(得分:0)
是
不要担心“虚拟内存”问题:除了你可能没有支持虚拟内存的系统之外,从你的 PoV你可以得到一个连续的内存块。就是这样。
答案 6 :(得分:0)
物理内存永远不会与其连续的逻辑内存连续。