【问题标题】:pointing to a memory address outside an array boundary [duplicate]指向数组边界外的内存地址[重复]
【发布时间】:2014-04-04 05:11:18
【问题描述】:

我想知道访问其边界之外的数组(以下代码示例中的第 2 行)是否会产生错误?

int a[20];
int* ptr = &a[20]; // line 2
int count=20;
do
{
  ptr--;
  printf("%d",*ptr);
}while(--count!=0);

【问题讨论】:

  • 这是 C 还是 C++?一个使&a[20] 定义明确,另一个引起热议。
  • 第一个甚至没有谈论如果使用上述语法可能会出现的任何错误

标签: c++ c


【解决方案1】:

根据C Traps and Pitfalls

但是引用一个不存在的元素又有什么意义呢?
幸运的是,我们不必参考这个元素,只需参考它的 地址,并且该地址确实存在于我们拥有的每个 C 实现中 遭遇。此外,ANSI C 明确允许这种用法:地址 可以采用刚刚超过数组末尾的不存在元素的 用于分配和比较目的。当然是违法的 实际上是引用那个元素!

【讨论】:

    【解决方案2】:

    试图访问超出数组末尾的内存是undefined behavior。但是,将指针指向数组末尾之外的一个元素是完全合法的。 指向某个地址和访问它之间的区别很重要。

    例如,您可以使用以下内容来查找数组的大小arr

    int size = (&arr)[1] - arr;
    

    【讨论】:

      【解决方案3】:

      访问数组边界之外的内存地址可能不会总是使进程崩溃。但是如果你修改数据,它肯定会破坏地址空间。此外,有时数组边界之外的内存地址实际上会位于进程地址空间之外,这将导致 seg-fault。
      无论如何,这是一个危险的。它将引入难以缩小的错误。内存损坏或程序的奇怪行为会在其他地方表现出来,我们将花费数小时和数小时在大海捞针。

      【讨论】:

        【解决方案4】:

        修改超出数组边界的地址永远不会产生编译器错误,因为 C 编译器不会将其视为错误。
        但是在某些机器上,如果不允许访问此地址,您可能会收到运行时错误(Seg Fault)。

        这类似于写地址0 (NULL)

        在某些架构上的微处理器/微控制器/嵌入式设备上,您可能被允许在地址0 上写入,这是完全有效的,但在其他一些机器上您可能会得到SEGFAULT

        这就是为什么它也被称为undefined behavior

        【讨论】:

          【解决方案5】:

          您的代码不会访问超出数组末尾的内存。 所以很少改变你的代码。 计数从 20 改为 100

          #include<stdio.h>
          
          int main() {
          int a[20];
          int* ptr = &a[20]; // line 2
          int count=100;
          do
          {
            ptr--;
            printf("%d",*ptr);
          }while(--count!=0);
          return 0;
          }
          

          http://codepad.org/X8yqrnDC

          NO 在编译时不会报错。

          但在运行时可能会出现分段错误。

          按照标准,其未定义行为

          【讨论】:

          • 没有。代码不会访问数组末尾之外的内存。
          • @MartinR 感谢更新答案
          • 实际上我只想指向数组之外的内存,而不是访问它...我会更新我的问题。
          • @thunderbird 如果您不打算访问它,那么为什么需要指向数组之外。?
          • @Mr.32 在我正在处理的嵌入式项目中使用类似的结构,只是想知道这样做是否合法。
          猜你喜欢
          • 1970-01-01
          • 2021-08-12
          • 2019-04-07
          • 1970-01-01
          • 2011-04-15
          • 2018-10-26
          相关资源
          最近更新 更多