I have searched on this site the topics about malloc
on structs. However, I have a slightly problem. Is that malloc
on the element of a struct different from malloc
on the whole struct, especially when that struct is quite simple, that is, only a member that is exactly what we all want to allocate? To be clear, see the code corresponding to student
and student2
structs below.
struct student {
int* majorScore;
};
struct student2 {
int majorScore[3];
};
int main()
{
struct student john;
john.majorScore = (int*) malloc(sizeof(int) * 3);
john.majorScore[0] = 50;
john.majorScore[1] = 27;
john.majorScore[2] = 56;
struct student2* amy= (struct student2*)malloc(sizeof(struct student2));
amy->majorScore[0] = 50;
amy->majorScore[1] = 27;
amy->majorScore[2] = 56;
return 0;
}
Are they different in memory level? If yes, what is the difference? If no, which is perhaps better in terms of a good programming style?
CodePudding user response:
First, you dynamically allocate one struct, but not the other. So you're comparing apples to oranges.
Statically-allocated structs:
struct student john;
john.majorScore = malloc(sizeof(int) * 3);
john.majorScore[0] = 50;
john.majorScore[1] = 27;
john.majorScore[2] = 56;
struct student2 amy;
amy.majorScore[0] = 50;
amy.majorScore[1] = 27;
amy.majorScore[2] = 56;
struct student john
------------ ---------- ----------
| majorScore | ------->| 50 |
------------ ---------- ----------
| [padding] | | | 27 |
------------ ---------- ----------
| 56 |
----------
struct student2 amy
------------ ----------
| majorScore | 50 |
| ----------
| | 27 |
| ----------
| | 56 |
------------ ----------
| [padding] | |
------------ ----------
struct student
uses more memory because it has an extra value (the pointer), and it has the overhead of two memory blocks instead of one.
struct student2
always has memory for exactly three scores, even if you need fewer. And it can't possibly accommodate more than 3.
Dynamically-allocated structs:
struct student *john = malloc(sizeof(struct student));
john->majorScore = malloc(sizeof(int) * 3);
john->majorScore[0] = 50;
john->majorScore[1] = 27;
john->majorScore[2] = 56;
struct student2 *amy = malloc(sizeof(struct student2));
amy->majorScore[0] = 50;
amy->majorScore[1] = 27;
amy->majorScore[2] = 56;
struct student *john
---------- ------------ ---------- ----------
| ------->| majorScore | ------->| 50 |
---------- ------------ ---------- ----------
| [padding] | | | 27 |
------------ ---------- ----------
| 56 |
----------
struct student2 *amy
---------- ------------ ----------
| ------->| majorScore | 50 |
---------- | ----------
| | 27 |
| ----------
| | 56 |
------------ ----------
| [padding] | |
------------ ----------
Same analysis as above.
CodePudding user response:
Is malloc on a struct simple? Sure, it certainly is. Although you don't need malloc whatsoever for your struct student2
definition, and I'd argue that just using the struct directly and avoiding malloc
is MUCH simpler. It's important to note that malloc
on a struct will only allocate the size of the struct itself, not the size of dynamic data pointed to by pointers within the struct. What you are comparing is two different structs with very different implementations, so it isn't really fair to say "which one is better" because it largely depends on your actual use cases.
For clarity, let's say you did struct student* john = malloc(sizeof(struct student))
. If you allocate storage for a struct like this, you still need to allocate memory for majorScore
since it the initial malloc
only allocates room for the int *
and nothing past that. As you can see, that complicates things even more.
So the conclusion is, in general you only want to use malloc
for dynamic memory allocation in circumstances where you may not know the size of data at compile time. There is no reason to introduce complexity (and likely bugs/leaks) through malloc
in the examples you have provided. The utility of using malloc
in your example for struct student
is that majorScore
can be an array of any size, not just 3 as in the struct student2
definition.