시나리오 1
int *nums = {5, 2, 1, 4};
printf("%d\n", nums[0]);
이것은 왜 세그 폴트입니까?
당신은 numsint에 대한 포인터로 선언 했습니다 . 이것은 메모리 nums에 하나의 정수 주소를 가지고 있어야합니다 .
그런 다음 여러 값 nums의 배열 로 초기화하려고했습니다 . 따라서 많은 세부 사항을 파헤 치지 않으면 개념적으로 잘못된 것입니다. 하나의 값을 보유해야하는 변수에 여러 값을 할당하는 것은 의미가 없습니다. 이와 관련하여 이렇게하면 정확히 동일한 효과를 볼 수 있습니다.
int nums = {5, 2, 1, 4};
printf("%d\n", nums);
두 경우 모두 (포인터 또는 int 변수에 여러 값 할당) 그러면 변수가 첫 번째 값 5인를 가져 오지만 나머지 값은 무시됩니다. 이 코드는 준수하지만 할당에 포함되지 않아야하는 각 추가 값에 대해 경고를받습니다.
warning: excess elements in scalar initializer.
포인터 변수에 여러 값을 할당하는 경우에, 프로그램 세그먼테이션 폴트 (segfault) 당신은에 액세스 할 때 nums[0],에 저장되어 당신이 무엇을 deferencing하는 수단 주소 (5) 문자를. nums이 경우 포인터 에 유효한 메모리를 할당하지 않았습니다 .
int 변수에 여러 값을 할당하는 경우에는 segfault가 없다는 점에 주목할 가치가 있습니다 (여기서는 잘못된 포인터를 역 참조하지 않습니다).
시나리오 2
int nums[] = {5, 2, 1, 4};
이것은 합법적으로 스택에 4 개의 int 배열을 할당하고 있기 때문에 segfault가 아닙니다.
시나리오 3
int *nums = {5, 2, 1, 4};
printf("%d\n", nums);
이것은 포인터 자체의 값을 인쇄 하고 있기 때문에 예상대로 segfault가 아닙니다 -참조가 아닌 (잘못된 메모리 액세스) 포인터 자체의 값을 인쇄하기 때문 입니다.
기타
이와 같은 포인터의 값 을 하드 코딩 할 때마다 거의 항상 segfault가 운명적입니다 (어떤 프로세스가 어떤 메모리 위치에 액세스 할 수 있는지 결정하는 것이 운영 체제 작업이기 때문입니다).
int *nums = 5;
따라서 경험상의 규칙은 다음과 같이 할당 된 변수 의 주소에 대한 포인터를 항상 초기화하는 것입니다.
int a;
int *nums = &a;
또는,
int a[] = {5, 2, 1, 4};
int *nums = a;