开发者

Can a variable be used to define the size of an array on the stack in c?

I have a situation where I want my program to read in some numbers that will define the size of a two dimensional array (used as a matrix). I originally argued that the only way to do this would be to use a malloc call to put the array on the heap, something like this:

matrixElement* matrix = malloc(sizeof(matrixElement) * numRows * numCols);

where numCols and numRows are the integers which were read in earlier, and matrixElement is some arbitrary type. My reasoning was that simply writing:

matrixElement matrix[numRows][numCols];

would not work since the compiler would have no way of knowing how much stack space to allocate to the function call. It turns out I was wrong, since the following code compiles and runs:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int x, y;
    scanf("%d", &x);
    scanf("%d", &y);

    double arr[x][y];

    printf("Made an array of size %d by %d, total memory %fKb\n", 
            sizeof(arr) / sizeof(arr[0]), 
            sizeof(arr[0]) / sizeof(arr[0][0]),
            (float) sizeof(arr) / 1024.0f);

    return 0;
}

With big enough numbers input for x and y, this will eventually give 开发者_Python百科a segfault, but I was very surprised too see that I could create a 1000x1000 array with this code.

Can anyone explain what is going on here?

Is the compiler just allocating a bunch of space for the array, even though it has no idea how much will be used?

Is this behavior specified by ANSI C or is it just something that gcc is doing on its own?


This feature was added in C99. The array is allocated on the stack similarly to how it would have been if you had called alloca(). There may be some subtle differences; check your compiler documentation for information.

The GCC documentation has a description of their implementation.


C99 added support for variable length arrays (sometimes called "VLAs"). Many C compilers also had support for this prior to C99. Many also supported an "alloca" function, that did the same thing, though in a slightly less convenient way.

Typical implementations allocate the "correct" amount of space. Essentially, the stack pointer is just adjusted based on the size of your variable length array. Some extra book keeping needs to be done to ensure that the stack pointer is "popped" the right amount upon returning, and that auto variables placed on the stack are accessed at the correct offset.


You should be as much surprised by the fact that you can declare your arr array in the middle of the block, as you are surprised by its variable-specified size. Both are new features of C99 language specification. Both were supported by GCC compiler as an extension to C89/90 for a while. But neither is legal in "classic" ANSI C, i.e C89/90.

If you are compiling your code in C89/90 mode (which is default in GCC), then you are indeed dealing with something GCC is doing on its own accord. If you are compiling your code in -std=c99 mode, you are dealing with [relatively] new standard languages features.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜