Originally Posted by
cencaluk
What I found out and the reason I'm asking here, upon running main() and checking using sizeof(student_data) for both examples, Structure B (the nested one) ended up using far more memory! It seems so conterintuitive that I thought I may have done something wrong (that I hope you could tell), or is my understanding on this whole memory allocation thing is totally wrong (if so, I'd appreciate if you could point me to a good direction to read up more).
You are probably observing the effects of padding for alignment, i.e., the amount of space occupied by a struct object may be more that the sum of the amount of space occupied by each of its members because there may be padding bytes in between.
Originally Posted by
cencaluk
In the above struct, if I am not mistaken, the size of the struct is 24 bytes for one data. So for the 3 students, Amy, Joe and Jack, then the size of the memory used by default would be initialized to 24*3 = 72.
Because sizeof(char) == 1, it is certain that the name and lastname members will occupy at least 10 bytes each. However, sizeof(int) is at least 1 byte, typically at least two bytes, and probably 4 bytes, i.e., it is implementation defined.
For me, sizeof(int) == 4, and sizeof(struct student_college_detail) == 32. This brings back the topic of padding: even though the sum of the sizes of the members is 10 + 4 + 10 + 4 == 28, I got 32 because of padding for alignment. I did a simple rearrangement of members:
Code:
struct student_college_detail
{
char name[10];
char lastname[10];
int college_id;
int age;
};
and now sizeof(struct student_college_detail) == 28 because no padding was needed.
Originally Posted by
cencaluk
Since only Amy has full information on herself, I thought it would be a waste of memory for Joe and Jack because the memory for lastname, college_id and age would be allocated automatically at the outset even when there is no other info for Joe and Jack other than their Name. So I figured I would create a nested struct.
That would not result in less memory being used: each student_college_detail object will contain a struct extra_details member for which memory will be allocated. All that you did was some rearrangement.
Originally Posted by
cencaluk
Or is there another way to really structure the Example so that memory is allocated only if information exist? Again, I'm a complete hack at programming, and I'd be very grateful for any enlightenment.
Yes, at the cost of increased complexity. For example:
Code:
struct extra_details
{
int college_id;
int age;
char lastname[10];
};
struct student_college_detail
{
char name[10];
struct extra_details *stu_details;
};
Now, stu_details is a pointer. So, if you need the extra details, you can malloc space for the struct extra_details object. But this means you have to consider that malloc could return a null pointer, and then you must call free at some point. Also, while you may reduce the memory used, you could also increase it: if all the records have these extra details, then not only is memory dynamically allocated for them anyway, but memory is also allocated for each stu_details pointer.
Furthermore, you presented a very specific case where two out of three students don't need these "extra details". What if most students need them? What if a student record provides everything except last name? If you want to make everything optional, you could end up with:
Code:
struct student_college_detail
{
char *name;
char *lastname;
int *age;
int *college_id;
};
This could lead to more complication. In short, I would suggest that you stick to the simpler version, unless you really have need of the complexity.
By the way, you should avoid global variables.