SCENARIUSZ 1
int *nums = {5, 2, 1, 4};
printf("%d\n", nums[0]);
Dlaczego ten się rozbija?
Zadeklarowałeś nums
jako wskaźnik do int - nums
to ma zawierać adres one liczby całkowitej w pamięci.
Następnie próbowałeś zainicjować nums
tablicę wielu wartości. Tak więc bez zagłębiania się w wiele szczegółów jest to koncepcyjnie niepoprawne - nie ma sensu przypisywanie wielu wartości zmiennej, która ma mieć jedną wartość. Pod tym względem zobaczysz dokładnie ten sam efekt, jeśli zrobisz to:
int nums = {5, 2, 1, 4};
printf("%d\n", nums);
W każdym przypadku (przypisz wiele wartości do wskaźnika lub zmiennej int), wtedy zmienna otrzyma pierwszą wartość, która jest 5
, a pozostałe wartości są ignorowane. Ten kod jest zgodny, ale otrzymasz ostrzeżenia dla każdej dodatkowej wartości, która nie powinna znajdować się w przypisaniu:
warning: excess elements in scalar initializer
.
W przypadku przypisywania wielu wartości do zmiennej wskaźnikowej, program segfaults podczas uzyskiwania dostępu nums[0]
, co oznacza, że dosłownie odrzucasz wszystko, co jest zapisane pod adresem 5 . W tym przypadku nie przydzieliłeś żadnej prawidłowej pamięci dla wskaźnika nums
.
Warto zauważyć, że nie ma segfaulta w przypadku przypisania wielu wartości do zmiennej int (nie wyłuskujemy tutaj żadnego nieprawidłowego wskaźnika).
SCENARIUSZ 2
int nums[] = {5, 2, 1, 4};
Ten nie powoduje segfaultów, ponieważ zgodnie z prawem przydzielasz tablicę 4 int w stosie.
SCENARIUSZ 3
int *nums = {5, 2, 1, 4};
printf("%d\n", nums);
Ten nie działa zgodnie z oczekiwaniami, ponieważ drukujesz wartość samego wskaźnika - NIE tego, co wyłuskuje (co jest nieprawidłowym dostępem do pamięci).
Inni
Prawie zawsze jest skazane na segfault za każdym razem, gdy zakodujesz wartość takiego wskaźnika (ponieważ zadaniem systemu operacyjnego jest określenie, który proces może uzyskać dostęp do jakiej lokalizacji pamięci).
int *nums = 5;
Tak więc ogólną zasadą jest, aby zawsze inicjalizować wskaźnik do adresu jakiejś przydzielonej zmiennej, takiej jak:
int a;
int *nums = &a;
lub,
int a[] = {5, 2, 1, 4};
int *nums = a;