Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

arrays

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 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?

like image 404
Graphics Noob Avatar asked Dec 09 '22 18:12

Graphics Noob


2 Answers

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.

like image 165
Carl Norum Avatar answered May 29 '23 08:05

Carl Norum


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.

like image 30
Laurence Gonsalves Avatar answered May 29 '23 08:05

Laurence Gonsalves