简体   繁体   English

arrays 是否保证在虚拟 memory 中是连续的?

[英]Are arrays guaranteed to be contiguous in virtual memory?

int main() { 
 char a[3] = {1,2,3};
 return sizeof(a);
}

Is a guaranteed to be in consecutive bytes in virtual memory?是否保证在虚拟 memory 中是a字节? I know it may not be consecutive in physical memory as the mapping is done behind the scene by the MMU.我知道它在物理 memory 中可能不是连续的,因为映射是由 MMU 在幕后完成的。

If the compiler notices i'm not taking the address of any of the elements, is it then free to put them on non consecutive addresses in memory or even put them in a register?如果编译器注意到我没有获取任何元素的地址,那么是否可以自由地将它们放在 memory 中的非连续地址上,甚至将它们放在寄存器中?

Let's assume the optimizer will not fully get rid of it in my example.假设在我的示例中优化器不会完全摆脱它。

Is a guaranteed to be in consecutive bytes in virtual memory?是否保证在虚拟 memory 中是连续字节? I know it may not be consecutive in physical memory as the mapping is done behind the scene by the MMU.我知道它在物理 memory 中可能不是连续的,因为映射是由 MMU 在幕后完成的。

Your code is guaranteed to behave as-if the array was in consecutive bytes of address space.保证您的代码的行为就像数组位于地址空间的连续字节中一样。

If the compiler notices i'm not taking the address of any of the elements, is it then free to put them on non consecutive addresses in memory or even put them in a register?如果编译器注意到我没有获取任何元素的地址,那么是否可以自由地将它们放在 memory 中的非连续地址上,甚至将它们放在寄存器中?

It is free to do so even if you do take the address.即使您确实获取了地址,也可以免费这样做。 The compiler can compile your code any way it wants to make it efficient so long as the code doesn't break.只要代码不中断,编译器就可以以任何方式编译您的代码以使其高效。

Let's assume the optimizer will not fully get rid of it in my example.假设在我的示例中优化器不会完全摆脱它。

Okay.好的。 But it's allowed to.但这是允许的。 C has an "as-if" rule which means that all rules are just about the behavior your code has to observe, they don't constrain how the compiler (or the machine) get that behavior. C 有一个“as-if”规则,这意味着所有规则都只是关于您的代码必须遵守的行为,它们不会限制编译器(或机器)如何获得该行为。

The non-pedantic answer is that, yes, for all intents and purposes, arrays are guaranteed to be stored contiguously in C.非迂腐的答案是,是的,出于所有意图和目的,arrays 保证连续存储在 C 中。 This is no accident, it's pretty much a fundamental part of the definition of an array.这绝非偶然,它几乎是数组定义的基本部分。

The whole point of an array is that you can access any element in constant (that is, O(1)) time, notionally by computing an address, and without having to chase any links as you would with almost any other data structure.数组的全部意义在于,您可以在恒定(即 O(1))时间内访问任何元素,理论上是通过计算地址,而无需像使用几乎任何其他数据结构一样追逐任何链接。 So if, as some obscure and invisible implementation detail, an array were somehow not actually stored contiguously, it would always have to act exactly as if it were stored contiguously.因此,如果作为一些晦涩且不可见的实现细节,数组实际上并没有连续存储,那么它总是必须完全像连续存储一样。 And since contiguity is the defining property of an array, I don't think there's any harm in thinking consciously about that property, and assuming that it's always true.而且由于连续性是数组的定义属性,我认为有意识地思考该属性并假设它总是正确的没有任何害处。

Well in this particular code snippet most likely a will be stored in the stack and yes in this particular case it would be contiguous.那么在这个特定的代码片段中,很可能a将存储在堆栈中,是的,在这种特殊情况下它是连续的。

However if you were to run at a higher optimization most likely any compiler would not even store a and just do constant propagation and just return the size of a .但是,如果您要以更高的优化运行,则很可能任何编译器都不会存储a ,而只是进行持续传播并仅返回a的大小。

If you were to allocate memory in heap then it depends on the allocator most likely if it is Buddy or slab allocator then more often than not they would be contiguous but if i were to have a naive free linked list allocator then it may not be contiguous when there are multiple calls for heap allocation.如果您要在堆中分配 memory ,那么它很可能取决于分配器,如果它是好友或平板分配器,那么它们通常是连续的,但如果我有一个天真的免费链表分配器,那么它可能不是连续的当有多个堆分配调用时。 In case of Arrays this is not possible as you most likely will have single call so it would still be contigous.在 Arrays 的情况下,这是不可能的,因为您很可能会有单个呼叫,因此它仍然是连续的。

Tools like objdump, opt from llvm, gdb etc are great tools if you want to check the disassembly and how the compiler lays out the assembly code across different optimization levels.如果您想检查反汇编以及编译器如何跨不同优化级别布置汇编代码,则 objdump、llvm 选择、gdb 等工具是很好的工具。

C is defined in terms of an abstract machine. C 是根据抽象机定义的。 The bytes are guaranteed to be contiguous in the abstract machine.字节在抽象机中保证是连续的。

The real machine can do literally anything so long as the observable behaviour of the program matches an allowed output of the program in the abstract machine.只要程序的可观察行为与抽象机器中程序的允许 output 匹配,真实机器实际上可以做任何事情。

So, there are no guarantees about any placement of data in the real machine.因此,不能保证数据在真机中的任何位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM