Home > Back-end >  Dynamic allocation outside the scope of a function
Dynamic allocation outside the scope of a function

Time:01-17

If I want to create an array that works as global variable, in case I already know the size I can do it this way:

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

int array[]={1,1,1,1};

int main()
{
    printf("%d", array[0]);
}

however, this will not work with malloc. Indeed, the following code

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

int* array=malloc(4*sizeof(int));

int main()
{
    printf("%d", array[0]);
}

will return an error (error: initializer element is not constant). Yet there is no problem if I try to do the same inside the scope of the function.

I believe there must be something I am missing about how dynamic allocation works.

What is going on? How can define an array dynamically outside the scope of any function and the use them as a global variable?

CodePudding user response:

In C language the code can be executed only in the function bodies.

The second code is invalid as you try to call malloc outside the function.

Using global variables in C is considered as a bad practice, so try to avoid it if not 100% necessary.

If you want to have a global pointer:

int *array;

int main(void)
{
     array = malloc(100);
     /* .... */
}

Some compilers support non-standard extensions. For example, in GCC you can use the attribute to execute the code before the function main is called

int* array;

void __attribute__((constructor)) aray_const(void)
{
    array = malloc(4 *sizeof(*array));
    if(array) memcpy(array, (int[]){1,2,3,4}, 4 * sizeof(*array));
}

int main()
{
    printf("%d %d %d %d\n", array[0], array[1], array[2], array[3]);
     /* .... */
}

https://godbolt.org/z/bz4YjzfK5

CodePudding user response:

In C objects with static storage duration may be initialized by a constant expression. And the pointer array declared in your second program in the file scope has static storage duration as any object declared in file scope.

From the C Standard (6.7.9 Initialization)

4 All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

Also the function malloc allocates non-initialized memory. So this call of printf

printf("%d", array[0]);

in any case can invoke undefined behavior.

You can rewrite your program for example the following way using the assignment operator in main

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

int *array;

int main( void )
{
    size_t n = 4;
    array = malloc( n * sizeof( int ) );

    if ( array != NULL )
    {
        int value = 1;
        for ( size_t i = 0; i < n; i   )
        {
            array[i] = value  ;
        }

        for ( size_t i = 0; i < n; i   )
        {   
            printf( "%d ", array[i] );
        }
        putchar( '\n' );
    }

    free( array );
}

Or you could use function calloc instead of malloc. In this case the allocated memory will be zero-initialized.

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

int *array;

int main( void )
{
    size_t n = 4;
    array = calloc( n, sizeof( int ) );

    if ( array != NULL )
    {
        for ( size_t i = 0; i < n; i   )
        {   
            printf( "%d ", array[i] );
        }
        putchar( '\n' );
    }

    free( array );
}

Pay attention to that you should always free allocated memory when it is not required any more.

  • Related