0

2 questions about the below code:

1 Why is the size of struct b 12 bytes (line 2 of output)? I can understand why a is 12 bytes (to align k on the 4 byte boundary), however shouldnt b be 9 bytes and not 12?

2 Why is using the & operator to get the address of the char members not displaying a valid address? (middle output in the last 2 lines)

#include<iostream>
using namespace std;
struct a
{
    int i;
    char j;
    int k;
};
struct b
{
    int i;
    int k;
    char j;
};
int main()
{
    a s1;
    b s2;

    cout<<sizeof(a)<<endl;
    cout<<sizeof(b)<<endl;
    cout<<sizeof(int)<<endl;
    cout<<sizeof(char)<<endl;
  cout<<&s1.i<<'\t'<<&s1.j<<'\t'<<&s1.k<<endl;
  cout<<&s2.i<<'\t'<<&s2.j<<'\t'<<&s2.k<<endl;
}

Output:

12
12
4
1
0x28ff14        -       0x28ff1c
0x28ff08         4A     0x28ff0c
Akash
  • 1,716
  • 2
  • 23
  • 43
  • 1
    The address of a `char` is `char *`. Think about that for a moment. Perhaps there is an overload `operator <<` for streams that writes such pointers as null-terminated strings rather than address values. Hmmmm.... – WhozCraig Dec 06 '14 at 12:38
  • 1
    1) also alignment. 2) `char*` is treated as C_String. – BLUEPIXY Dec 06 '14 at 12:39
  • Please online ask one question at a time and search SO before you do. – Jens Gustedt Dec 06 '14 at 15:12

2 Answers2

3

If b were 9 bytes large and you had an array

b foo[2];

then foo[1].i would not be aligned to four-byte boundaries.

As for the char members, their address is of type char *, and std::ostream has an operator<< for those that interprets them as a C-style string. If you want to see their address, static_cast<void*>(&s1.j) is your friend.

EDIT: Full disclosure of egg on my face: This originally stated that some compilers defined minimum struct alignment sizes; upon investigation, this turns out to be untrue. Well, it could be true, since the size of struct types is not specified in the standard to that extent, but common compilers don't appear to do it. Sorry about that.

Wintermute
  • 42,983
  • 5
  • 77
  • 80
  • Ok.. so alignment is compiler dependent? there isnt any padding happening when using only chars in the struct. with 1,2 or 3 chars, it uses 1,2 or 3 bytes respectively (this is codeblocks on Windows, so I guess MinGW) – Akash Dec 06 '14 at 12:42
  • Oh, true -- gcc under Linux does that as well. I'll amend the answer to reflect that. And I'd better check that MSVC behaves the way I think it does. Update: It does not. I better fix that, then. – Wintermute Dec 06 '14 at 12:46
1

Why is the size of struct b 12 bytes (line 2 of output)?

It has int fields, and so has the same alignment requirement as int - four bytes, in your case. Three padding bytes are added at the end, so the size is a multiple of four, to give the required alignment.

This applies even at the end of the structure, so that the next element of an array is properly aligned.

Why is using the & operator to get the address of the char members not displaying a valid address?

Because << interprets a pointer to a character type as a pointer to a C-style string, and prints memory contents until it finds a zero value. To print the address, cast to a non-character pointer type:

cout << (void*)&j;
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Is the padding guideline that enough padding should be added to align to the largest data type? – Akash Dec 06 '14 at 12:44
  • @Akash: Basically, yes. The exact rules are a bit more complicated, but you usually don't need to worry about the finer details. – Mike Seymour Dec 06 '14 at 12:45
  • However a struct with a `long long` (8), an `int`(4) and a`char`(1) shows a size of 16 (8+4+(1+3)) as opposed to 24 (8+(4+4)+(1+7)) – Akash Dec 06 '14 at 12:47
  • @Akash: The `char` field doesn't need any particular alignment, so can follow on straight after the `int`. Padding is only needed at the end, for the overall requirement of 8 (due to the `long long`). – Mike Seymour Dec 06 '14 at 12:50
  • oh, ok.. so the primary aim of the padding is to ensure that the entire `struct` is aligned and not individual members? – Akash Dec 06 '14 at 12:53
  • @Akash: Each member has its own requirement, and must be aligned accordingly within the structure. The overall structure has the strictest requirement of any of its members. So here, the requirements are (probably) 8 for `long long`, 4 for `int`, 1 for `char`, and 8 (the largest of these) for the structure. – Mike Seymour Dec 06 '14 at 12:56