1

I have this structure in my code:

struct BlockDescriptor
{
    struct BlockDescriptor * pNext;
    bool _isFree;
};

and I am inclined to believe its size is 4 + 1 = 5 (4 for the pointer and 1 for the bool), but for some reason sizeof(struct BlockDescriptor) returns 8 ! Can someone tell me why?

Is it because of packing issues that 5 is rounded up to a multiple of 4 (since 32 bits is what most computers are most comfortable with ) and is there some way to force it to use the true size (if that is in fact the true size) ?

LihO
  • 41,190
  • 11
  • 99
  • 167
angryInsomniac
  • 829
  • 2
  • 13
  • 27

3 Answers3

1

The data members of struct are being aligned by default. There might be padding between these data members as well as padding after the last data member. In your case the padding will be most likely at the end.

The first data member is a pointer, which in your case requires 4 bytes of memory. Then although the other member is a char that requires only 1 byte of memory, there is a padding up to the multiple of 4, but the reason is not because "32 bits is what most computers are most comfortable with" as you say, but because 4 is the size of the largest data member.

Usually there is a pragma directive allowing you to specify custom alignment available. In Visual Studio, there is #pragma pack, that might help you in this case. Just make sure you know what you are doing. Although you will minimize the memory usage, it might negatively affect the performance of your code.

For more information have a look at related questions:
How to minimize the memory usage of a struct-type?
How does sizeof calculate the size of structures
Is the size of a struct required to be an exact multiple of the alignment of that struct?
or even Determining the alignment of C/C++ structures in relation to its members

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
  • Yup, the alignment is defined by the size of the largest data member I cant believe I forgot that :P and if my programming professor saw that I would get a thorough pounding :) – angryInsomniac Mar 17 '13 at 22:26
0

Posting the answer courtesy of : Luka Rahne and cnicutar

There is Padding between pNext and _isFree. You can enforce "packing" via compiler-specific mechanisms, put #pragma pack(1) before struct definition

angryInsomniac
  • 829
  • 2
  • 13
  • 27
0

When the CPU accesses memory to fetch a data item (or struct member), it actually sends a request to the memory controller, which performs some trickery to make the DRAM appear to be a well-structured data store. In reality, DRAM is a bunch of cells, arranged in M rows of N bits each (where N could be a thousand or so).

Knowing that most architectures process 4, 8, 16 or 32 (or sometimes larger) bits at a time, memory controllers are optimized for fetches from addresses that are multiples of 4. What happens when you fetch a single byte from the address abcd1002? Well, the memory controller fetches four bytes from the address abcd1000, then shifts them to obtain the third byte (remember, it's 0, 1, then 2), and gives you your lousy non-aligned byte. Thus, fetching from an aligned address is always faster than from a non-aligned one.

Aware of this fact, compilers aggressively optimize for speed by padding data structures so that they're laid out in a memory-friendly way.

Hope that provides an important computer architecture perspective on this issue. I did not see this mentioned in any of the current responses, hence I felt like adding my $0.02.

Rahul Banerjee
  • 2,343
  • 15
  • 16