I have a struct defined in this way.
typedef struct COUNTRY {
char Code[3];
char Country[30];
int Population;
float Expectancy;
struct Country *Pointer;
} COUNTRY;
I have seen an array of structs allocated like this:
COUNTRY *countries = calloc(128, sizeof(COUNTRY));
or maybe like this:
COUNTRY *countries = malloc(128 * sizeof(COUNTRY));
But what does this do:
COUNTRY countries[128] = {};
Because I am still able to write to each entries' fields in all cases. Is the third option just bad form? It seems better to me because you can put that line up with the rest of your variable declarations outside of main(). Otherwise, you can only calloc() or malloc() inside of main() or other function.
Am I doing something wrong?
If you want to dynamically allocate arrays, you can use malloc from stdlib. h . If you want to allocate an array of 100 elements using your words struct, try the following: words* array = (words*)malloc(sizeof(words) * 100);
Actually you can use free without calling malloc , but only if the value you pass to free is a null pointer. So not useful if what you want is a pointer which might point to an allocated block, but might point to a local array.
To allocate a new person in the myperson argument, we use the following syntax: person * myperson = (person *) malloc(sizeof(person)); This tells the compiler that we want to dynamically allocate just enough to hold a person struct in memory and then return a pointer of type person to the newly allocated data.
As it turns out, you do not need to use malloc() in every case. malloc() will allocate memory on the heap when it is used, but there is nothing stopping you from defining an object on the stack and initializing a pointer to a struct with the address of your stack-allocated struct.
This:
COUNTRY countries[128];
simply defines an object whose type is "array of 128 COUNTRY
elements".
The = {}
is an initializer -- but empty initializers are illegal in C (I think gcc supports them as an extension). A portable alternative is:
COUNTRY countries[128] = { 0 };
which initializes all members of all elements to zero (0
for integers, \0'
for characters, 0.0
for floating-point, NULL
for pointers, and recursively for sub-elements). But since you specified the number of elements in the array (as 128
), the initializer has no effect on how the array object is allocated.
If the declaration occurs inside a function definition, the array object has automatic storage duration, which means that it ceases to exist when execution reaches the end of the enclosing block. Such objects are commonly allocated on "the stack".
If it occurs outside any function definition (at file scope) or if it has the keyword static
, then it has static storage duration, which means that it continues to exist for the entire execution of the program.
Objects allocated with malloc
or calloc
have allocated storage duration, which means that they continue to exist until they're explicitly deallocated by a call to free()
. Such objects are commonly allocated on "the heap". (I'm ignoring realloc()
, which complicates the description a bit.)
The first two statements will allocate array of structs on the heap, while the last one will initialize the array of structs on the stack.
It is not a bad form, it is just a matter where you want your data to be stored - on the stack ( freed automatically when your variable goes out of the scope, stack usually have significantly smaller size then heap, so you could overflow it if you place big data structures there), or on the heap (lifetime of data is not related to the scope, you need to manually free your memory).
It seems better to me because you can put that line up with the rest of your variable declarations outside of main().
If you need statically allocated object with the lifetime of the program, use this approach, there's nothing wrong with it. Please note that in this particular case, variable is not stored on the stack, but in the .data
segment of your program (check this question for more details: How are global variables stored?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With