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.