Używam gcc w wersji 4.7.2 na Ubuntu 12.10 x86_64.Zarządzanie pamięcią C w gcc
Przede wszystkim są to rozmiary typów danych na moim terminalu:
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
Teraz proszę spojrzeć na ten fragment kodu:
int main(void)
{
char c = 'a';
printf("&c = %p\n", &c);
return 0;
}
Jeśli się nie mylę to możliwe” t przewidzieć cokolwiek na temat adresu c
. Ale za każdym razem ten program daje losowy adres heksadecymalny kończący się na f
. Tak więc następna dostępna lokalizacja będzie miała wartość szesnastkową kończącą się na 0
. Ten wzór zaobserwowałem również w przypadku innych typów danych. Dla wartości int adres był pewną wartością szesnastkową kończącą się na c
. Dla double była to losowa wartość heksadecymalna kończąca się na 8
i tak dalej.
Mam więc 2 pytania tutaj.
1) Kto zarządza tego rodzaju przydzielaniem pamięci? Czy jest to standard gcc lub C?
2) Ktokolwiek to jest, dlaczego tak jest? Dlaczego zmienna jest przechowywana w taki sposób, że następna dostępna lokalizacja pamięci zaczyna się od wartości szesnastkowej kończącej się na 0
? Jakieś szczególne korzyści?
Teraz proszę spojrzeć na ten fragment kodu:
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;
}
Teraz oto co zauważyłem jest zupełnie nowy dla mnie. Myślałem, że zmienna zostanie zapisana w tej samej kolejności, w jakiej zostały zadeklarowane. Ale nie! Nie o to chodzi. Oto przykładowe dane wyjściowe jednego z losowym Run:
&a = 0x7fff8686a698
&b = 0x7fff8686a694
&c = 0x7fff8686a691
&d = 0x7fff8686a692
Wydaje się, że zmienne get sortowane w kolejności rosnącej ich rozmiarów, a następnie są one przechowywane w tej samej kolejności posortowanej ale z utrzymaniem obserwację 1. czyli ostatnia zmienna (największa) zostaje zapisana w taki sposób, że następna dostępna lokalizacja pamięci jest wartością szesnastkową kończącą się na 0
.
Oto moje pytania:
3) Kto za tym stoi? Czy jest to standard gcc lub C?
4) Po co tracić czas na sortowanie zmiennych, a następnie przydzielanie pamięci zamiast bezpośredniego przydzielania pamięci na zasadzie "kto pierwszy ten lepszy"? Jakieś szczególne korzyści z tego rodzaju sortowania, a następnie przydzielania pamięci?
Teraz proszę spojrzeć na ten fragment kodu:
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;
}
Teraz jest to również dla mnie szokujące. Co zauważyłem jest to, że tablica jest zawsze przechowywany w jakiś przypadkowy wartość hex kończące się na „0”, jeśli obserwacja elements of an array >= 2
a jeśli elements < 2
wtedy robi się miejsce w pamięci po 1.
Więc oto moje pytania:
5) Kto stoi za tym przechowywaniem tablicy przy pewnej losowej wartości heksadecymalnej kończącej się na 0
rzeczy? Czy jest to standard gcc lub C?
6) Dlaczego warto marnować pamięć? Chodzi mi o to, że array2
mógł być przechowywany natychmiast po array1
(a tym samym array2
miałby miejsce w pamięci kończące się na 2
). Ale zamiast tego array2
jest przechowywany przy następnej wartości heksadecjalnej kończącej się na 0
, pozostawiając 14 miejsc pamięci pomiędzy nimi. Jakieś konkretne korzyści?
Nie ma "standardu". Może zależeć od wersji używanego kompilatora, ABI, jądra, środowiska, w którym uruchamiasz ten program, itp. ABI prawdopodobnie nakazuje, aby wskaźnik stosu był wyrównany do 16 bajtów, a kompilator umieścił zmienne w "jak chce ". A tablica 'array2' musi być wyrównana do słowa (wielokrotność 4 bajtów), podczas gdy' tablica1' nie musi być ... –
Dlaczego numery pokoi po tej stronie korytarza są wszystkie * nawet *? Dlaczego numery pokoi po przeciwnej stronie korytarza są wszystkie * nieparzyste *? – wildplasser
Dlaczego dokładnie pytasz? Jaki jest powód twojego pytania i dlaczego naprawdę cię to obchodzi? (Nie powinieneś kodować programów, które zależą tak ściśle od dokładnej przyczyny tego). –