C全局未大小数组



我们有一个学校项目,任何使用c的信息系统。为了保持一个动态大小的学生记录列表,我采用了链表数据结构。今天早上我朋友让我看看他的系统。我对他的记录列表感到惊讶:

#include <stdio.h>
/* and the rest of the includes */
/* global unsized array */
int array[];
int main()
{
    int n;
    for (n=0; n < 5; n ++) {
         array[n] = n;
    }

    for (n=0; n < 5; n ++) {
         printf("array[%d] = %dn", n, array[n]);
    }
    return 0;
}

与代码一样,他声明了一个对整个程序全局(在bss段中)的未大小数组。他能够通过使用非零的值覆盖后续内存块来向数组添加新条目,这样他就可以遍历数组:

for (n=0; array[n]; n++) {
    /* do something */
}

他使用(我也测试了它)Turbo C v1。我在linux中尝试过,它也可以工作。

由于我以前从未遇到过这种技术,所以我认为它有问题。所以,是的,我想知道为什么这是一个坏主意为什么更喜欢这个而不是链表

int array[];

在技术上称为不完全类型的数组。简单地说,它相当于:

int array[1];

这并不好,因为:

  1. 产生未定义行为。不完整类型数组的主要用法是Struct Hack。注意,不完整数组类型在C99中是标准化的,在此之前是非法的。

这是未定义行为。您正在写入未分配的内存(超出数组)。为了编译这个,编译器至少分配一个元素,然后你再写。尝试更大范围的数字。例如,如果我在Linux上运行您的代码,它可以工作,但如果我将循环更改为50,000,它就会崩溃。

EDIT代码可能适用于n的小值,但对于较大的值将失败。为了演示这一点,我编写了您的代码并在n = 1000上进行了测试。

这里是CODEPAD的链接,您可以看到,当n = 1000时,会发生分段错误

然而,使用相同的代码和相同的编译器,它可以为n = 10工作,请参阅此链接CODEPAD。这叫做未定义行为

如果您使用链表,您可以检查内存是否分配正确。

int *ptr;
ptr = (int *)malloc(sizeof(int))
if(ptr==NULL)
{
  printf("No Memory!!!");
}

但是在您的代码中,如果使用具有较大边界的数组进行测试,则程序只会崩溃。

相关内容

  • 没有找到相关文章

最新更新