是否保证数组的元素从较低地址到较高地址存储?

Rüp*_*ure 3 c arrays stack memory-address

假设我有以下数组:

int list[3]={2,8,9};
printf("%p,%p,%p",(void*)&list[0],(void*)&list[1],(void*)&list[2]);
Run Code Online (Sandbox Code Playgroud)

是否始终保证&list [0] <&list [1] <&list [2]

在使用C时我曾经认为它是一个严格而快速的规则,但现在必须非常肯定它作为一个OP只是在我回答他的问题时问我这个问题. endianness

小端或大端

什么让我第二个想法是问题.stacks can grow up or down我不是很确定,所以你的严谨答案是值得赞赏的.谢谢.

int*_*jay 6

是的,保证&list[0]<&list[1]&list[1]<&list[2].当比较指向同一数组元素的指针时,指向具有较大下标的元素的指针将被视为具有更大的值.这在C99 6.5.8@5中规定:

指向具有较大下标值的数组元素的指针比指向具有较低下标值的相同数组的元素的指针要大

但是,不能保证printf打印的值%p也遵循相同的顺序 - 这些值是实现定义的.


Jim*_*mbo 5

从C标准("第6.2.5节类型"):

...数组类型描述了一组连续分配的非空对象...

数组将在"内存"中连续分配.

Eric和Interjay在说什么,这是我最初写这篇文章时没有考虑过的,所以谢谢Eric和Interjay,这只适用于虚拟内存地址.

您的机器和操作系统很可能使用内存管理单元(MMU)来创建虚拟地址空间(您正在工作的地方)并将其映射到块大小的块(页面)中的物理内存.

所以Eric和Interjay所说的是虽然虚拟地址是连续的,但是它们映射到的物理内存块可能位于不同的地址.

 Virtual               Physical
+----------+           +----------+
|          |           |
| VMA pg 1 |---------->| PMA 88 (VMA1)
|          |           |
+----------+           +----------+
|          |\           ...
| VMA pg 2 | \          ...
|          |  \         ...
+----------+   \        ...
             \  \       ...  big gap in physical
              \  \      ...  memory
               \  \     ...
                \  \    ...
                 \  >--+----------+
                  \    |
                   \   | PMA 999 (VMA2)
                    \  |
                     >-+----------+
Run Code Online (Sandbox Code Playgroud)

因此,对于小型阵列(小于页面大小),对于VMA和PMA地址都可能是这样,尽管很可能是PMA!= VM​​A.对于大于页面大小的数组,尽管VMA看起来是连续的,但PMA可能是不相交的并且不正常,如上图所示...

此外,我认为Interjay和Eric更进一步说,任何C地址虽然在C模型中是连续的,但可能在内存中的任何地方.虽然这不太可能,因为大多数操作系统实现某种分页以获得虚拟到物理映射,但从技术上来说,我认为这样做...这是很好的学习考虑,所以谢谢你们:)