내가 좋은 중복 답변을 찾을 수없는, 그래서 여기에 무슨 일이 일어나고 있는지의 :
포인터 연산은 항상 포인터의 기본 유형의 단위로 발생합니다. 즉, T *ptr
(일부 유형 T
에 대한 포인터)이 있으면 ptr + 1
은 메모리의 다음 바이트가 아니지만 다음은 T
입니다. 즉
, 당신은 배열의 조합 및 인덱스와 같은 포인터 상상할 수 : array[n]
(n 번째 요소)에 대한 포인터가
T *ptr;
T array[/*some size*/];
ptr = &array[n];
ptr
경우를 다음 ptr + i
는 array[n + i]
에 대한 포인터입니다 ((n + i) 번째 요소).
은의 당신의 코드를 살펴 보자 : 당신이 그것에
32
을 추가 한 후,
basepointer
에
(int*)
을 캐스팅하고 여기에
*((int*)basepointer+32) = 455;
. 그러면 basepointer
뒤에 32 번째 주소 (int
)가 표시됩니다. 플랫폼이 4 바이트 정수를 사용하는 경우 실제 오프셋은 32 * 4 = 128
바이트입니다. 이곳에 455
을 저장합니다.
그런 다음 당신은 basepointer
이 void *
때문에이 기술적으로 유효하지 않은 번호 및 void
더 크기가 없기 때문에 당신이 void
의 관점에서 연산을 수행 할 수 없습니다
void *p = basepointer + 32;
을한다. 확장 기능으로 gcc는 이것을 지원하며 void
은 크기가 1
인 것처럼 가장합니다. (하지만 당신은 정말이에 의존해서는 안 : 캐스트를 unsigned char *
에 주소 지정의 바이트합니다.) basepointer
후 32
오프셋에서
지금 p
이다.
a = *((int*)basepointer+32);
이것은 위에서 포인터 연산을 반복 여전히 455
32 int
오프셋의 값 (즉 128
바이트 오프셋), 검색한다.
b = *((int*)p);
이 바이트에 저장된 값은 int
(int
에 대응할 것이다 이러한 예에서 오프셋 8
) 32
오프셋을 검색한다. 여기서 아무 것도 저장하지 않으므로 b
은 기본적으로 가비지입니다 (플랫폼에서 0
일 수 있습니다).예상대로
작은 변화
이
void *p = (int *)basepointer + 32; // use int-wise arithmetic to compute p
대신 두 번째 줄에'* (int *) (basepointer + 32) = 455;'를 사용해보십시오. 그런 다음 포인터 연산에 대해 읽어보십시오. – aragaer
@aragaer'basepointer'가'void *'타입이라면 좋지 않습니다. – aschepler
기본 포인터의 유형은 무엇입니까? – Bathsheba