Выравнивание
Давайте посмотрим на ваш вывод для печати адресов a, b и c:
Вывод: 0x7fff91a15c58 0x7fff91a15c5f 0x7fff91a15c54
Заметьте, что b не находится на той же 4-байтовой границе?А что а и с рядом друг с другом?Вот как это выглядит в памяти: каждая строка занимает 4 байта, а самый правый столбец занимает 0-е место:
| b | x | x | x | 0x5c5c
-----------------
| a | a | a | a | 0x5c58
-----------------
| c | c | c | c | 0x5c54
Это способ компиляции оптимизировать пространство и поддерживать выравнивание слов.Даже если ваш адрес b равен 0x5c5f, на самом деле он не занимает 4 байта.Если вы возьмете тот же код и добавите короткий d, вы увидите это:
| b | x | d | d | 0x5c5c
-----------------
| a | a | a | a | 0x5c58
-----------------
| c | c | c | c | 0x5c54
Где адрес d равен 0x5c5c.Шорты будут выровнены на два байта, поэтому у вас останется один байт неиспользуемой памяти между c и d.Добавьте еще один символ, и вы получите:
| b | e | d | d | 0x5c5c
-----------------
| a | a | a | a | 0x5c58
-----------------
| c | c | c | c | 0x5c54
Вот мой код и вывод.Обратите внимание, что мои адреса будут немного отличаться, но это наименее значимая цифра в адресе, которая нас действительно беспокоит:
int main(void)
{
int a;
char b;
int c;
short d;
char e;
a = 0;
b = 'b';
c = 1;
printf("%p\n",&a);
printf("%p\n",&b);
printf("%p\n",&c);
printf("%p\n",&d);
printf("%p\n",&e);
return 0;
}
$ ./a.out
0xbfa0bde8
0xbfa0bdef
0xbfa0bde4
0xbfa0bdec
0xbfa0bdee
Malloc
На странице руководства malloc сказано, чтоон " выделяет размер байтов и возвращает указатель на выделенную память ."В нем также говорится, что он « вернет указатель на выделенную память, который соответствующим образом выровнен для любой переменной ».Из моего тестирования повторные вызовы malloc (1) возвращают адреса с приращением «двойного слова», но я бы не стал рассчитывать на это.
Предостережения
Мой код был запущен на x8632-битная машина.Другие машины могут немного отличаться, и некоторые компиляторы могут оптимизировать по-разному, но идеи должны быть верными.