Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating an Array of Structs without Malloc?

Tags:

arrays

c

struct

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?

like image 944
chrissphinx Avatar asked Sep 19 '13 17:09

chrissphinx


People also ask

How do you dynamically allocate an array of structs?

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);

Can you free without malloc?

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.

How do you allocate memory to struct?

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.

Should I always use malloc?

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.


2 Answers

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.)

like image 87
Keith Thompson Avatar answered Nov 14 '22 23:11

Keith Thompson


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

like image 29
Nemanja Boric Avatar answered Nov 14 '22 23:11

Nemanja Boric