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?

Gilad Naor
  • 20,752
  • 14
  • 46
  • 53
kiokko89
  • 211
  • 2
  • 7

4 Answers4

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.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
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))

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
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...

Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
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).

EmeryBerger
  • 3,897
  • 18
  • 29
  • 2
    I know of no architecture that requires alignment on 12 byte boundaries. Are you aware of any? – Billy ONeal Jan 09 '11 at 16:57
  • 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? – EmeryBerger Jan 09 '11 at 18:22
  • i'm using the visual studio compiler with a x64 machine (sorry again for my bad English) – kiokko89 Jan 09 '11 at 19:11