简体   繁体   中英

C global unsized array?

We had a school project, any information system using C. To keep a dynamic-sized list of student records, I went for a linked list data structure. This morning my friend let me see his system. I was surprised with his list of records:

#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] = %d\n", n, array[n]);
    }
    return 0;
}

As with the code, he declared an unsized array that is global (in the bss segment) to the whole program. He was able to add new entries to the array by overwriting subsequent blocks of memory with a value other than zero so that he can traverse the array thusly:

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

He used (I also tested it with) Turbo C v1. I tried it in linux and it also works.

As I never encountered this technique before, I am presuming there is a problem with it. So, yeah, I wanna know why this is a bad idea and why prefer this over a linked list.

int array[];

Is technically known as an array with incomplete type . Simply put it is equivalent to:

int array[1];

This is not good simply because:

  1. It produces an Undefined behavior . The primary use of array with incomplete type is in Struct Hack . Note that incomplete array types where standardized in C99 and they are illegal before.

This is Undefined behaviour . You are writing to unallocated memory (beyond the array). In order to compile this, the compiler is allocating at least one element, and you're then writing beyond that. Try a much bigger range of numbers. For example, if I run your code on Linux it works, but if I change the loop to 50,000, it crashes.

EDIT The code may work for small values of n but for larger values it will fail. To demonstrate this I've written your code and tested it for n = 1000 .

Here is the link for CODEPAD , and you can see that for n = 1000, a segmentation fault happens.

Whereas with the same code with the same compiler, it is working for n = 10, see this link CODEPAD . So this is called Undefined behavior .

If you use linked lists you can check whether the memory is allocated properly or not.

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

But with your code the program simply crashes if tested with an array having a large bound.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM