新的[]是否连续分配内存?

10
当我使用new[]关键字(或new运算符)时,它是否会连续分配内存?
int* arr = new int[10];

我的意思是,是否有保证arr[0]arr[1]紧密放置,并且我可以使用指针增量迭代arr?如果是这样,那么结构体和类行为是否与int相同?


4
物理内存可以从分散的页面中分配,但是分配的内存的虚拟地址空间将是连续的。 - rcgldr
@DOUGLASO.MOEN:对我来说,这是一个愚蠢的话,但我忍不住要说:自C++03以来,std::vector的连续性才得到保证。 - Bathsheba
2个回答

16

C++标准绝对保证了这一点。

arr[0]arr[9]是连续的,在元素之间不允许有填充。在分配的区域中,指针算术运算是有效的。您可以将指针设置为arr + 10,但是不要对其进行解引用。

这适用于任何类。每个元素分配的内存量为sizeof(Y),其中Y是类或普通数据类型。


结构体/类的末尾会填充以获得正确的对齐方式。但是sizeof将包括填充,因此数组将是连续的。 - Sergei
@DOUGLASO.MOEN 你打算如何使用 sizeof() 来检测填充的存在? - François Andrieux
sizeof(YourClass)与每个数据成员的sizeof之和的总和 - Sergei
所以,如果我分配了1000个数组,每个数组有10000个元素,是否可能出现下一个new[]抛出bad_alloc的情况,因为内存碎片化导致没有任何连续的块可以容纳10000个元素? - Alexey Larionov
1
@AlexLarionov 是的,这是可能的。但在今天的典型计算机上,需要比10000个元素或非常大的元素更多的元素才能达到这种可能性。 - Mark Ransom

2

是的,这些元素保证在连续内存中(与它们的类型无关)。当您调用new[]时,您会得到一个数组,实际上访问元素的唯一方法是通过指针算术。

考虑一下arr[i]实际上意味着什么:

arr[i]

实际上只是的缩写形式

*( ( arr ) + (i) )

这个问题的一个有趣副作用是,对于一个数组arr和一个索引i
i[arr]

arr[i][]完全相同(尽管您只会写这个代码来困惑您的同事)。

但是,请注意,[]可以被重载,在这种情况下,它可以执行任何实现选择的操作。然而,使用new[]分配的数组,如果有重载的oeprator[],其元素也将在连续的内存中。


1
如果有多个答案,SO 的效果最佳,从我的回答中借用文本并没有什么坏处。 - Bathsheba
另外,如果你专注于[]符号,你可能想指出它可以被重载。 - Bathsheba
谢谢你的友好留言。我只是试图提出一个简单的问题,而没有实际的实现。 - Alexey Larionov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接