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?
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.
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))
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With