2016-09-27 3 views
-1

Адресное пространство переменных, по-видимому, меняется в моей программе. Сначала я получил следующий результат из приведенной ниже программы.адресное пространство переменных, изменяющихся в программе c

int main(){ 
int a = 10; 
int *b = &a; 
int **c = &b; 
int ***d = &c; 
printf("a - address: %p, value: %x\n",&a ,a); 
printf("b - address: %p, value: %x\n",&b ,b); 
printf("c - address: %p, value: %x\n",&c ,c); 
printf("d - address: %p, value: %x\n",&d ,d); 
printf("size: a - %d, b - %d c- %d, d - %d", sizeof(a), sizeof(b), sizeof(c), sizeof(d)); 
} 

Выход:

a - address: 0x7ffc08c5866c, value: a 
b - address: 0x7ffc08c58660, value: 8c5866c 
c - address: 0x7ffc08c58658, value: 8c58660 
d - address: 0x7ffc08c58650, value: 8c58658 

который имеет разницу между адресом a и b как 0xc.

затем добавить:

int f = 10; 

я получаю этот выход:

f - address: 0x7fff1945656c, value: a 
a - address: 0x7fff19456568, value: a 
b - address: 0x7fff19456560, value: 19456568 
c - address: 0x7fff19456558, value: 19456560 
d - address: 0x7fff19456550, value: 19456558 

Разница между адресом a и b изменилось. Может ли кто-нибудь сказать мне, почему?

+1

Компиляторы могут свободно организовывать память для вашей переменной по своему усмотрению ... Если вам нужно больше объяснений, прочитайте о выравнивании и дополнении в C. Также не забудьте напечатать значения указателя с помощью '% p'. –

+0

Вы получаете разные адреса, запускающие одну и ту же программу дважды? Это может быть связано с рандомизацией размещения стека. – 1201ProgramAlarm

+0

нет, поскольку я добавляю объявления int перед int a, разница между адресом a и адресом b изменяется от 12 до 4 до 12. –

ответ

0

int занимает 4 байта, а указатель занимает 8 байтов. Указатель работает «лучше», если его адрес кратен 8, то есть шестнадцатеричный адрес заканчивается на 8 или 0.

int также имеет выравнивание 4. Таким образом, два int s может быть сохранен в той же как один указатель. Когда вы добавляете f, он использует первые 4 байта и «нажимает» a 4 байта дальше. Эти байты ранее не использовались, так что b мог начинаться с 8-байтовой границы.

Это все еще оставляет место для указателя b, чтобы начать с того же 0-адреса, который использовался раньше.

Смежные вопросы