2

Currently we are trying to keep track of the variables stored in memory, however we have faced with the following issues, maybe you would help us out

Currently we defined some global variables in our code, as follows

int x;
char y;

And we added the following lines of code

int main ( int argc, char *argv[ ] ){ 
printf("Memory of x %p\n",&x); 
printf("Memory of y %p\n",&y);
system( "pause");
return 0;
}

The program returned the following address

Memory of x 0x028EE80
Memory of y 0x028EE87

If I make a sizeof x and a sizeof y I get 4 and 1 (the size of types integer and char) What is then in between 0x028EE84 and 0x028EE86? why did it took 7 positions in order to insert the char variable in memory instead of inserting it on the 0x028EE81 memory position?

3 Answers3

2

In general, the compiler will try to do something called alignment. This means that the compiler will try to have variables ending on multiples of 2, 4, 8, 16, ..., depending on the machine architecture. By doing this, memory accesses and writes are faster.

user3264405
  • 330
  • 1
  • 3
2

There are a number of very good answers here already however I do not feel any of them reach the very core of this issue. Where a compiler decides to place global variables in memory is not defined by C or C++. Though it may appear convenient to the programmer to store variables contiguously, the compiler has an enormous amount of information regarding your specific system and can thus provide a wide array of optimisations, perhaps causing it to use memory in ways which are not at first obvious.

Perhaps the compiler decided to place the int in an area of memory with other types of the same alignment and stuck the char among some strings which do not need to be aligned.

Still, the essence of this is that the compiler makes no obligations or promises of where it will store most types of variables in memory and short of reading the full sources of the compiler there is no easy way to understand why it did so. If you care about this so badly you should not be using separate variables, consider putting them into a struct which then has well defined memory placement rules (note padding is still allowed).

Vality
  • 6,577
  • 3
  • 27
  • 48
  • Thanks for the struct suggestion. It actually helped me solve a problem (checksumming large blocks of variables). – MV. Jul 27 '19 at 23:51
1

Because the compiler is free to insert padding in order to get better alignment.

If you absolutely must have them right next to each other in memory, put them in a struct and use #pragma pack to force the packing alignment to 1 (no padding).

#pragma pack(push, 1)

struct MyStruct
{
    int x;
    char y;
};

#pragma pack(pop)

This is technically compiler-dependent behavior (not enforced by the C++ standard) but I've found it to be fairly consistent among the major compilers.

Community
  • 1
  • 1
TypeIA
  • 16,916
  • 1
  • 38
  • 52