【问题标题】:Are the addresses of array elements guaranteed to increase数组元素的地址是否保证增加
【发布时间】:2019-05-09 12:47:00
【问题描述】:

当我定义和初始化一个数组a:

如果(&(a[x]) > &(a[y])) 成立,则暗示x > y 是否绝对安全?

我担心一些我不知道的奇怪的异常内存地址。

【问题讨论】:

  • 谢谢 :) (忘了补充,我为堆上分配内存,但我认为这不会影响您的回答,是吗?)
  • 你发现了什么?是什么让您认为它不是,或者至少比较表现得好像?

标签: c


【解决方案1】:

是的,这是有保证的。 C standard 中关于关系运算符的第 6.5.8p5 节指出:

比较两个指针时,结果取决于 指向的对象在地址空间中的相对位置。 如果两个指向对象类型的指针都指向同一个对象,或者 都指向同一数组的最后一个元素 对象,它们比较相等。如果指向的对象是 同一聚合对象的成员,指向结构的指针 稍后声明的成员比较大于指向的指针 结构中早先声明的成员,以及 指向 具有较大下标值的数组元素比较大于 指向具有较低下标值的同一数组元素的指针。
指向同一联合对象成员的所有指针比较 平等的。如果表达式 P 指向数组的元素 对象和表达式 Q 指向的最后一个元素 同一个数组对象,指针表达式Q+1比较大于P .在所有其他情况下,行为未定义

因此,即使您有奇怪的内存布局,该语言也保证具有较高下标的数组元素的地址将比具有较低下标的数组元素的地址更大。只要数组下标有效,比较就会成立。

【讨论】:

  • 特别适用于 x86 等预计堆栈向下增长的架构。
  • @GovindParmar 即使在堆栈上,x86 上对象的字节数仍然会增加。只是新的堆栈对象是在较低的地址创建的。
【解决方案2】:

是的。如果x>y&a[x] > &a[y],如果数组的两个元素都存在,或者a[x] 是数组末尾之后的一个元素。否则行为未定义。

注意:我看到您的问题与我上面的答案相反。反之亦然:如果地址更大,则其索引更大,如果地址是相隔的整数个元素。通常编译器会处理这个并且&a[x]+1&a[x+1]。编译器将第一个表达式中的+1 转换为添加元素大小的字节数。

【讨论】:

    【解决方案3】:

    因为 (1) a[x]*(a+x),因此 (2) &(a[x]) = a+x

        x < y 
    =>  a+x < a+y
    => &(*(a+x)) < &(*(a+y))  // from (2)  
    => &(a[x]) < &(a[y])      // from (1)
    

    【讨论】:

      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多