1

假设您有一个包含 10 个元素的 int arr[] 和一个 int * ptr。我认为以下几行会导致错误,但它会打印 0 作为存储在 ptr 中的值。它是如何计算为0的?

ptr = arr;//ptr currently points to the first element in arr
ptr = (arr + 10);//points to what would be the llth element in memory for arr
printf("ptr %p\n", ptr);//this displays where the 11th element would be in memory
printf("*ptr %i\n", *ptr);//why would this print 0?
4

2 回答 2

6

越界访问数组是未定义的行为。这意味着任何事情都可能发生,比如崩溃,或者打印出 0 或任何其他数字,你只是无法事先知道实际会发生什么。

这正是未定义行为如此邪恶的原因,您甚至可能没有注意到有问题,因为它似乎工作正常。当您尝试对其进行测试时,您甚至可能在计算中得到正确的结果,并且在您下次运行它时可能会给您带来错误。

于 2013-11-03T02:56:06.743 回答
1

请注意,ANSI C 要求如果您定义:

SomeType array[10];

那么地址&array[10](相当于array + 10)必须是有效地址。但是,不允许取消引用该有效地址;这样做会调用未定义的行为,并且任何事情都可能发生。也就是说,最常见的行为是读取了其他一些变量,但您无法先验地判断哪个其他变量,它可能是函数的返回地址或其他意外的东西。

因此,您可以运行如下循环:

SomeType *end = array + 10;

for (SomeType *src = array; src < end; src++)
{
    ...use `*src` to reference the current row of the array...
}

另一个后果是,可以放置在可寻址存储器最顶部的内容是有限制的。然而,这些问题很少受到关注(除非您正在使用内存非常小的嵌入式微型计算机)。

于 2013-11-03T03:55:39.960 回答