7

Consider the following code:

struct CExample  {
    int a; 
}            

int main(int argc, char* argv[]) {  

    CExample ce1;  
    CExample ce2;  

    cout << "Size:" << sizeof(ce1) << " Address: " << &ce1 << endl;   
    cout << "Size:" << sizeof(ce2) << " Address: " << &ce2 << endl;   

    CExample ceArr[2];
    cout << "Size:" << sizeof(ceArr[0])<< " Address: "<< &ceArr[0] <<endl;
    cout << "Size:" << sizeof(ceArr[1])<< " Address: "<< &ceArr[1] <<endl;

    return 0;
}

Output example:
ce1: Size=4, Address: 0039FAA0
ce2: Size=4, Address: 0039FA94
ceArr[0]: Size=4, Address: 0039FA84
ceArr[1]: Size=4, Address: 0039FA88

With the code there is a 12-byte between the addresses of the first two objects (ce1 and ce2) but there is only a 4-byte difference between the objects in the array.

I thought data-alignment would have something to do with the issue, but I'm still stumped. Any idea what is actually going on here?

1
  • 2
    What's the output of the above? Mind posting that as well in code? Commented Jan 9, 2011 at 16:51

4 Answers 4

15

Because objects in an array are required to be contiguous. Objects declared consecutively on the stack(in source code, not machine) are not[required to be contiguous], although they can be.

Sign up to request clarification or add additional context in comments.

2 Comments

Well, they can be, but they are not required to be.
Sorry.. misread that. The second sentence, read by itself, seems to say that they are never contiguous. Sorry :(
6

The standard says nothing about this. The compiler is free to insert whatever padding it wants between the items.

(If I had to guess, I'd guess that your compiler implements some form of stack protection/canary in debug mode (and that you are compiling in debug mode))

2 Comments

Possible it is reserving space of temporary objects, (or maybe there is an Easter egg their?
Yes you're right! I've tried to compile in release mode and it worked as I expected!
1

The compiler does not only use the stack for keeping your local variables - it also uses it for example for argument passing, and some of the overhead caused by std::cout. That's probably what the extra space between your variables is used for.

If you instead make your variables static, like this:

static CExample ce;
static CExample ce2;

static CExample ceArr[2];

...the variables will be placed in BSS memory instead, and the alignment will more likely be what you expect.

The reason why arrays are packed, and individual items are not, is clarified by other answers...

Comments

0

The reason is that, on most architectures, unaligned loads are slow. See the Wikipedia entry on data structure alignment for a good explanation. The compiler places each one of your data structures at the start of a data word. However, in arrays, the items are placed contiguously in memory (as the C++ standard requires).

3 Comments

I know of no architecture that requires alignment on 12 byte boundaries. Are you aware of any?
Nope. OP hadn't posted output (IIRC), which shows it is not an alignment issue. I assumed the poster meant 12 bytes = 16 bytes minus the 4 bytes from the original object. When I compiled it on my Mac, I got the expected 16 bytes difference. @kiokko89 - not that it matters, but what compiler / platform are you using?
i'm using the visual studio compiler with a x64 machine (sorry again for my bad English)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.