Home > front end >  The size of a variable is 12 bytes, but why the address of the variable shows me that it took 15 byt
The size of a variable is 12 bytes, but why the address of the variable shows me that it took 15 byt

Time:10-05

I used the follow the code.

#include <stdio.h>
int main()
{
  char a;
  int b[3];
  printf("%d \n", sizeof(b));
  printf("%p \n", &a);
  printf("%p \n", &b);

  return 0;
}

The size of int b[3] is 12. But I got the address of a is 000000000061FE1F, and the address of b is 000000000061FE10. The difference between the two addresses is 15 but not 12.

When I define b[3] as char b[3]. It doesn't have such a problem. The char size of b[3] is 3. I got the address of a is 000000000061FE1F, and the address of b is 000000000061FE1C. The difference between the two addresses is 3.

One more question: I define a first, the address of a should be smaller than b. why here are b bigger than a?

CodePudding user response:

As pointed out in comments, the compiler can optimize memory areas allocated to variables.

What this shows however is about memory aligment. A char is one byte and thus does not need to be aligned to 2, 4, or 8 bytes unlike (u)int16_t, (u)int32_t, or (u)int64_t.

Play around within a structure definition, you will be surprised!

CodePudding user response:

this is due to something called alignment of variable, suppose sizeof(int) = 4 and a = 0 and b[0] = 0; b[1] = 0; b[2] = 0; and the width of the memory = 4 and the stack pointer is descending not ascending then look at the next image:

enter image description here

so any int variable should be stored at only the addresses which are multiples of 4 which is the width of the memory and char variable can be stored at place in the memory which are multiples of 1.

so what happens is when you wrote :

char a;
int b[3];

this made a created in the stack in the begging of place which is a multiple of 4. and for b its start address should be stored in address which is multiple of 4 and the first place that matches this condition is at address &a - 0x04 so the start address of b will be 0x0018. this something done by the compiler to make MCU fetch values from the memory faster.

in your case, the compiler optimizes the placement of int variable by placing it in addresses which are multiple of 16. so if the address of a is 000000000061FE1F, then address of b = &a - 0x0F = 000000000061FE10.

this is just some compiler optimization to make you MCU faster when fetching values from the memory and there will be a place in the memory which is padded and not use.

how to solve it

just declare the variable with variable attribute aligned.

refer to enter image description here

so I edited your code according to GCC and this is the edited code:

#include <stdio.h>
int main()
{
  char a = 0;
  int b[3] __attribute__ ((aligned (1))) = {0};
  printf("%p \n", &a);
  printf("%p \n", &b);
  printf("%d \n", sizeof(b));

  return 0;
}

and this is the output:

00000018eabffbef
00000018eabffbe3
12

where the difference between the 2 addresses is 12.

  •  Tags:  
  • c
  • Related