Я использую gcc версии 4.7.2 на Ubuntu 12.10 x86_64.Управление памятью в gcc
Прежде всего, это размеры типов данных на моем терминале:
sizeof(char) = 1
sizeof(short) = 2 sizeof(int) = 4
sizeof(long) = 8 sizeof(long long) = 8
sizeof(float) = 4 sizeof(double) = 8
sizeof(long double) = 16
Теперь, пожалуйста, посмотрите на этот фрагмент кода:
int main(void)
{
char c = 'a';
printf("&c = %p\n", &c);
return 0;
}
Если я не ошибаюсь, мы можем» t предсказывать что-нибудь об адресе c
. Но каждый раз эта программа дает случайный шестнадцатеричный адрес, заканчивающийся f
. Таким образом, следующим доступным местоположением будет некоторое шестнадцатеричное значение, заканчивающееся на 0
. Я наблюдал этот шаблон и в случае других типов данных. Для значения int адрес имел некоторое шестнадцатеричное значение, заканчивающееся на c
. Для double это было некоторое случайное шестнадцатеричное значение, заканчивающееся на 8
и так далее.
У меня есть 2 вопроса.
1) Кто управляет таким распределением памяти? Это стандарт gcc или C?
2) Кто бы это ни был, почему это так? Почему переменная хранится таким образом, что следующая доступная ячейка памяти начинается с шестнадцатеричного значения, заканчивающегося 0
? Любая конкретная выгода?
Теперь, пожалуйста, взгляните на этом фрагменте кода:
int main(void)
{
double a = 10.2;
int b = 20;
char c = 30;
short d = 40;
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
printf("&d = %p\n", &d);
return 0;
}
Теперь вот что я наблюдал это совершенно новое для меня. Я думал, что переменная будет храниться в том же порядке, в котором они объявлены. Но нет! Это не так. Вот пример вывода одного случайного запуска:
&a = 0x7fff8686a698
&b = 0x7fff8686a694
&c = 0x7fff8686a691
&d = 0x7fff8686a692
кажется, что переменные упорядочиваются в порядке возрастания их размеров, а затем они хранятся в том же порядке сортировки, но с сохранением наблюдения 1. т.е. последний переменная (самая большая) хранится таким образом, что следующая доступная ячейка памяти является шестнадцатеричным значением, заканчивающимся на 0
.
Вот мои вопросы:
3) Кто за этим? Это стандарт gcc или C?
4) Зачем тратить время на сортировку переменных, а затем выделение памяти вместо того, чтобы напрямую распределять память на основе «первым пришел первым»? Любое конкретное преимущество такого рода сортировки, а затем распределения памяти?
Теперь, пожалуйста, взгляните на этом фрагменте кода:
int main(void)
{
char array1[] = {1, 2};
int array2[] = {1, 2, 3};
printf("&array1[0] = %p\n", &array1[0]);
printf("&array1[1] = %p\n\n", &array1[1]);
printf("&array2[0] = %p\n", &array2[0]);
printf("&array2[1] = %p\n", &array2[1]);
printf("&array2[2] = %p\n", &array2[2]);
return 0;
}
Теперь это также шокирующим для меня. То, что я заметил, что массив всегда хранится в некоторой случайной шестнадцатеричное значение, оканчивающиеся на «0», если elements of an array >= 2
и если elements < 2
то он получает место в памяти следующее наблюдение 1.
Так вот мои вопросы:
5) Кто стоит за этим хранением массива при некотором случайном шестнадцатеричном значении, заканчивающемся на 0
? Это стандарт gcc или C?
6) Теперь зачем тратить память? Я имею в виду, что array2
может быть сохранен сразу после array1
(и, следовательно, array2
будет иметь ячейку памяти, которая заканчивается на 2
). Но вместо этого array2
хранится при следующем шестнадцатеричном значении, заканчивающемся на 0
, тем самым оставляя между ними 14 ячеек памяти. Какие-либо конкретные преимущества?
В действительности не задействованы никакие «стандарты». Это может зависеть от версии используемого компилятора, ABI, ядра, среды, в которой вы запускаете эту программу, и т. Д. ABI, вероятно, требует, чтобы указатель стека выравнивался по 16 байт, а компилятор помещал переменные в «как он хочет ». И 'array2' должен быть выровнен по слову (несколько из 4 байтов), в то время как' array1' не нужно ... –
Почему номера комнат на этой стороне коридора все * даже *? Почему номера номеров на противоположной стороне коридора все * нечетные *? – wildplasser
Почему именно вы спрашиваете? В чем причина вашего вопроса, и почему вам все равно? (Вы не должны кодировать программы, которые так сильно зависят от точной причины этого). –