访问未定义的外部数组

时间:2015-09-26 22:49:24

标签: c arrays undefined

我正在通过K& R工作,所以请原谅我对C的平庸理解。我试图将argv的值存储为外部数组中的int。所以我的第一个问题是:是否可以创建一个大小取决于argc的外部数组?或者除了使用任意长的数组并希望它都适合之外,还有其他解决方法。

第二,我正在尝试使用指向未定义整数数组的指针。我能够多次递增指针,从(几乎所有内容都为零)读取并在我收到“总线错误:10”之前写入指向的内存。有没有理由在我遇到总线错误之前能够访问这么多内存,或者这只是“未定义行为的一部分?”

以下是测试未定义数组的代码。

#include <stdio.h>

int main(void);
int test();

int a[];

int main(void)
{
    test();
}

int test()
{
    extern int a[];

    int *a0 = a;
    printf("%d\n", *a0);
    while (1) {
        *a0 = 1;
        a0++;
        printf("%d\n", *a0);
    }

    return 0;
}

2 个答案:

答案 0 :(得分:2)

  

是否可以创建一个大小取决于argc的外部数组?

不是真的。您可以分配一个数组并将指针存储到全局存储段中,但它可以是指针,而不是数组。

  

我能够多次递增指针,从(几乎所有内容都为零)读取并写入指向内存之后我得到一个&#34;总线错误:10。&#34;

阵列外的第一次读取或写入是非法的。事实上你没有得到&#34; Buss错误:10。&#34;马上就是一个不幸的巧合,因为代码可能在实际上不正确时起作用。

  

只是&#34;未定义行为的一部分?&#34;

是的,这是未定义的行为。

答案 1 :(得分:0)

首先,让我们澄清一下extern的作用。在C中,有一种称为翻译单元的东西。现在,想象它们只是.c文件。编译它们时,每个.c文件形成一个转换单元并生成一个目标文件(.o)。然后将目标文件放在一起以由链接器创建最终的可执行文件。有时您希望在一个翻译单元中定义(即&#34;创建&#34;)某些内容,如数组,但在多个翻译单元中使用它。只要C有关就可以了:一切都必须定义为ONCE,但可以多次使用。但是,您需要通知编译器您希望在另一个转换单元中定义的数组,而不是定义另一个数组。为此,请使用extern关键字。

在您的情况下,您的数组a只是一个全局数组,可以从此转换单元中的任何位置访问(即在此文件中)。因此,您并不需要使用extern关键字在main函数中声明它。

您真正想问的是,您是否可以创建一个大小等于argc的全局数组。

直到C99(K&amp; R是前C99),阵列的大小必须是恒定的。所以你必须创建一个足够大的数组。但是,您不应该希望它适合 - 这是创建错误和漏洞的一种非常常见的方式。相反,您应检查其用法是否合理,如果超出大小,则会生成错误。如果你不这样做,你会得到未定义的行为。它可能有用,也可能不行。它可能被用于恶意目的。

C99标准支持可变长度数组,所以你可以使用int a [argc] ;.但是,这只适用于本地数组。

解决方案是创建一个全局指针,并使用malloc函数在main函数中为它分配dinamically内存。

相关问题