4

What is the size of this struct? (32 bit system calculation. Not 64 bit.)

struct list_element
{
  short data;
  struct list_element* next;
  struct list_element* prev;
};

I have tried calculating the size with these formulas:

  1. (sizeof(list_element*) + sizeof(short)) + ((sizeof(list_element*) * 2)

    • (4 + 2) + (4 * 2) = 6 + 8 = 14
  2. (sizeof(short)) + (sizeof(list_element*) * 2)

    • 2 + (4 * 2) = 2 + 8 = 10
  3. (sizeof(list_element*) + sizeof(list_element*) + sizeof(short)) + (sizeof(list_element*) * 2)

    • (4 + 4 + 2) + (4 * 2) = 10 + 8 = 18
  4. (sizeof(list_element*) + sizeof(list_element*) + sizeof(short))

    • (4 + 4 + 2) = 10

However, they do not return the correct answer. What formula do you use to calculate the size of this struct?

Update:

My teacher says we a re ignoring data alignment... Hopefully that does not throw anyone off too much since you are used handling data alignment with your code and structs...

Update 2 Thank you for the help and the introduction to data alignment.

The answer was 10 without data alignment... Not sure why I am in such a rush to work with data alignment in C... Is it fun?

Also, the answer with data alignment is 12. As you guys explained, you have to data align the short to match the integers. Therefore, you have (2 + (2 additional bytes)) + 4 + 4 = 12.

Programmer MJM
  • 87
  • 1
  • 10
  • 10
    `sizeof(struct list_element)` – SleuthEye Oct 26 '14 at 00:30
  • 1
    (short with padding) + (struct list_element*)*2 – BLUEPIXY Oct 26 '14 at 00:31
  • 3
    possible duplicate of [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) – Bill Lynch Oct 26 '14 at 00:32
  • 4
    There is no formula that will give you the right answer. Your C compiler can decide to use as many extra padding bytes as the programmer who wrote it felt like wasting! – librik Oct 26 '14 at 00:37
  • @BLUEPIXY Does padding work by checking the previous data member to decide how much you need or is it the data member after? From the examples I see on the internet, you check the previous data member to determine the padding. – Programmer MJM Oct 26 '14 at 00:57
  • @BLUEPIXY plus, if you have to calculate the size of struct list_element*, then you will end up in a recursive loop in attempting to solve this right? – Programmer MJM Oct 26 '14 at 01:02
  • @librik My visual studios c compiler says the size is 12. Although the quiz will not take this answer. I really want to understand how to solve this type of question if I run across it again or have to deal with this in coding. – Programmer MJM Oct 26 '14 at 01:23
  • @SleuthEye I see what you are getting at but in my visual studios compiler give me 12 which is not the answer for some reason. – Programmer MJM Oct 26 '14 at 01:59
  • 1
    Then that "quiz" is garbage, because this is a question where there is no right answer that is always correct. Each compiler makes it different. I'll bet whoever wrote that quiz just checked what it was on his own compiler. Now you are smarter than he is. Delete the quiz. – librik Oct 26 '14 at 01:59
  • @librik My teacher made the quiz... She got her computer science degree from duke... So... Yeah... -____- – Programmer MJM Oct 26 '14 at 02:01
  • 1
    "compiler give me 12 which is not the answer for some reason" - no, this is proof that the answer is whatever the compiler says. There *is no formula* for this. Anyone who says there is (in the standard language) shouldn't be teaching. – Alex Celeste Oct 26 '14 at 02:56
  • @Leushenko I was trying to think mathematically and find a pattern for future reference. – Programmer MJM Oct 26 '14 at 02:59
  • It's good that you were trying - understanding the code at a low level may well come in handy later on. But you do need to know the difference between what *one* compiler (on *one* machine, with *one* set of options) actually does, and what the standard language demands. This cannot be computed from data available within the language itself - only with external knowledge about the implementation. – Alex Celeste Oct 26 '14 at 03:07
  • @Leushenko Thanks! I will keep that in mind and study more about the different compiler's alignment strategies and variable sizes. – Programmer MJM Oct 26 '14 at 03:17
  • http://ideone.com/KsNYYS – BLUEPIXY Oct 26 '14 at 07:12
  • @BLUEPIXY I almost forgot that ideone existed. I have not used it for a while... I hope you do not mind if I forked the code to my account. – Programmer MJM Oct 26 '14 at 18:03

3 Answers3

7

The size of the struct is given by:

size_t size = sizeof(struct list_element);

The fact that you have two members that are pointers to the struct just means you are adding the size of a pointer, twice. On a 32 bit build, sizeof would resolve to an additional 4 bytes per pointer, on a 64 bit build, it would result in an additional 8 bytes per pointer.

Another thing to be aware of is that the size of your struct is likely not simply the sum of the sizeof's of the individual members, as storage in a struct is often padded for alignment purposes. So, between your short, and the next member, the padding will result in additional size.

The reason I used the word likely is that if a pragma pack directive was used in your source, the packing alignment could be changed, resulting in a different value for sizeof.

Two good discussions on struct alignment padding: A general discussion here, and How to reduce memory footprint here. The second link is particularly interesting as it deals with structure alignment, padding and bit fields, and how each can affect memory usage.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • So that means you have to pad even though the short is before the pointer? Most examples I have seen on the internet show that you only calculate padding if the smaller data member is after the bigger data member. – Programmer MJM Oct 26 '14 at 01:00
  • I will give this a try. I may be looking at (4 + (4 *2)) = 12. – Programmer MJM Oct 26 '14 at 01:20
  • @rykker Thanks for the explanation! I will refer to this again when I have to deal with data alignment again. – Programmer MJM Oct 26 '14 at 03:01
  • 1
    @ProgrammerMJM - I have edited my post with two very good discussions on how padding works. But in regards to your question: _So that means you have to pad even though..._ Padding is required by processor architecture, not by language. You do not have to do anything for padding to happen, it happens automatically. – ryyker Oct 26 '14 at 16:38
  • In the 2nd article I noticed in the article that you can tell the compiler how much bytes to assign to a variable. If I were to do this would I run into issues of packaging errors by passing another 4 bit integer into a 1 bit integer? – Programmer MJM Oct 26 '14 at 18:06
  • 1
    You might be referring to the sections describing bitfield use (I am not sure) Keep in mind, an int will always contain `sizeof int` bytes (not bits). The best way to answer your question here is to try some of the interesting examples in that link, compile and size them yourself to see what the result will be. – ryyker Oct 26 '14 at 18:53
2

Although your teacher asked to ignore data alignment, the size of that struct is 10 bytes assuming short being 2 bytes.. but actually the short size is not fixed, but at least 2 bytes!

Give a look here. Did you correctly reported the teacher question?

gmas80
  • 1,218
  • 1
  • 14
  • 44
1

This will return the size of the struct:

sizeof(struct list_element);
Community
  • 1
  • 1
Shravan40
  • 8,922
  • 6
  • 28
  • 48