n大小的C数组的第n个索引是否包含它的大小?

时间:2015-10-07 20:27:55

标签: c arrays pointers garbage

我编写了一个C程序,用于使用指针显示数组的值。这是代码:

Capybara.page

正如您在终止循环后看到的那样,指针保存数组中值的内存地址。因为它没有初始化最后一个输出,所以它应该是垃圾值。但是,每次显示5是数组的大小。然后,我认为数组的已分配内存的下一个内存地址包含数组的大小。但是,双类型数组不会发生这种情况。

#include <stdio.h>

int main()
{
    int a[] = {1, 1, 1, 1, 1};
    int *ptr = a;
    for (int i = 0 ; i < 5; i++)
        printf("%d ", *ptr++);
    printf("%d", *ptr);
}

有人会解释输出吗?

3 个答案:

答案 0 :(得分:6)

这只是此地址中内存的值。您永远不应该访问未由您分配的内存(在这种情况下,您正在访问第6个元素,但您只声明了5个元素)。在某些情况下,这可能会导致分段错误。

答案 1 :(得分:3)

C不会在数组的开头或结尾处存储任何数组元数据(包括数组长度)。对于整数数组,输出的最可能的解释是变量i使用的内存紧跟在数组的最后一个元素之后,如下所示:

   +---+
a: | 1 | a[0]
   +---+ 
   | 1 | a[1]
   +---+
   | 1 | a[2]
   +---+
   | 1 | a[3]
   +---+
   | 1 | a[4]
   +---+
i: | 5 | a[5]
   +---+

但是,无法依赖此行为保持一致,正如您所看到的那样将数组类型更改为double

尝试读取元素末尾的元素中包含的值会导致未定义的行为Chapter and (truncated) verse

6.5.6附加运营商
...
8当一个具有整数类型的表达式被添加到指针或从指针中减去时, result具有指针操作数的类型... 如果结果指向一个超过数组对象的最后一个元素的那个,那么 不得用作被评估的一元*运算符的操作数。

对于咯咯笑,我在工作时在我的系统上编译了你的代码,我得到以下输出:

1 1 1 1 1 0

这实际上只是编译器如何为此特定程序在内存中放置对象的工件。

答案 2 :(得分:2)

你做的是调用未定义的行为

这很简单,可能只是i的值,打印i的地址并检查。但要小心,它并不总是这样。只需在程序中声明一个新变量,它就可能会发生变化。

对于double,它不起作用,因为数组后面的地址不再与i的地址匹配。当我说小心时,这就是我的意思。