Why is offsetof(member) equal to sizeof(struct)?
Asked Answered
B

3

5

I have a struct defined as:

struct smth
{
    char a;
    int b[];
};

When I call sizeof and offsetof on this struct:

cout << sizeof(struct smth) << endl;
cout << offsetof(struct smth, b) << endl;

Output is:

4
4

How come when the size of the stuct is 4 and char is using 1 byte, the offset of the int array is 4? Why is there some kind of padding? Also, why isn't the int array occupying any space at all?

Brogue answered 17/8, 2013 at 15:13 Comment(6)
You mean offsetof(struct smth, b), right?Fraught
@CarlNorum Yes, I do. Edited.Brogue
Is it C or C++? They are different.Cockatrice
@YuHao I am asking specifically for C++ but added c tag so people can find it with that tag as well. How are they different w.r.t. the answer of this question?Brogue
@biox6 You should tag the question with only the tag that's relative. C and C++ may be similar in many fields, they are different in more. In this question, e.g, variable length arrays are only valid in C, not C++.Cockatrice
@biox6 make it an b[1]; to see differencesRictus
F
8

How come when the size of the stuct is 4 and char is using 1 byte, the offset of the int array is 4? Why is there some kind of padding?

There is padding because the C standard allows it; the compiler often aligns variables to improve performance.

Also, why isn't the second variable occupying any space at all (which seems like the case)?

It's a C99 flexible array member - that's the entire point of it. The idea is to allocate your structure something like:

struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]);

And then you'd have a structure that operates as if b were a 10-element array.

Fraught answered 17/8, 2013 at 15:15 Comment(6)
What kind of performance improvements does this allow? Just curious.Brogue
@biox6, some processors load instructions can only load words from word-aligned addresses. If you have a word at an unaligned address, you'd need to load each byte separately and recombine.Fraught
Your allocation statement does not consider alignment constraints. In general it will fail to allocate the correct amount of memory. You would instead allocate a properly sized structure using struct smth *s = malloc(offsetof(struct smth, b[10]));.Dripstone
@IInspectable, how so? malloc is required to return safely-aligned pointers, and the structure is laid out correctly. What's the difference?Fraught
probably 10 * sizeof s->b[0]Tameshatamez
I'm sorry, brain-lag. I had something else altogether in mind. Consider it an alternative way to calculate the size rather than a correction. The trailing zero-sized array being part of the struct ensures proper alignment.Dripstone
S
3

Because the size of the member b is zero, and the compiler adds padding between the a and b members so that b is on a "word" boundary.

However, if I remember correctly having a flexible array in a structure like that is only valid C, not C++ except as a compiler extension.

Sella answered 17/8, 2013 at 15:16 Comment(5)
here is this int b[] equivalent to int *b?Moon
No it is not. int* b would make the sizeof(smth) larger, and the extra space would be where address of some int variable is to be stored. Instead, int b[] says the structure shall be allocated dynamically with some (unknown at compile time) number of integers as a single memory block.Ceasefire
@Ceasefire How do you assign value(s) to the variable b,could you give me the assignment statementMoon
@Moon See the answer from Carl Norum.Sella
@Light: Given struct smth *s = malloc(sizeof(*s) + 10*sizeof(*s->b));, you can write s->a = 'c'; s->b[0] = 0; s->b[9] = 9;, etc.Villus
C
2

Since OP comments that the question is C++:

struct smth
{
    char a;
    int b[];
};

An array like b[] is invalid in C++. The array must have fixed size. Variable length arrays are only valid in C99.

Assuming that your compiler supports it as extension, the array b[] has a size of zero, which makes the struct containing only a char member. The the rule of padding in struct works, padding the struct to a word, which is 4 bytes in your machine.

Cockatrice answered 17/8, 2013 at 15:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.