2017-04-30 7 views
0

포인터를 사용하여 값에 액세스 할 수 있기를 원합니다. 하지만 p 포인터를 사용할 때 항상 b 변수가 0이됩니다. 아래의 코드 스 니펫을 참조하십시오.C++에서 다른 포인터로 int에 액세스 할 수없는 이유는 무엇입니까?

basepointer = malloc(512);  
*((int*)basepointer+32) = 455; // putting int value in memory 
void *p = basepointer + 32;  // creating other pointer 
int a,b; 
a = *((int*)basepointer+32); // 455, retrieving value using basepointer 
b = *((int*)p);     // 0, retrieving value using p 

왜 그렇게됩니까? p 포인터로 값을 액세스하려면 어떻게해야합니까?

+1

대신 두 번째 줄에'* (int *) (basepointer + 32) = 455;'를 사용해보십시오. 그런 다음 포인터 연산에 대해 읽어보십시오. – aragaer

+1

@aragaer'basepointer'가'void *'타입이라면 좋지 않습니다. – aschepler

+0

기본 포인터의 유형은 무엇입니까? – Bathsheba

답변

3

내가 좋은 중복 답변을 찾을 수없는, 그래서 여기에 무슨 일이 일어나고 있는지의 :

포인터 연산은 항상 포인터의 기본 유형의 단위로 발생합니다. 즉, T *ptr (일부 유형 T에 대한 포인터)이 있으면 ptr + 1은 메모리의 다음 바이트가 아니지만 다음은 T입니다. 즉

, 당신은 배열의 조합 및 인덱스와 같은 포인터 상상할 수 : array[n] (n 번째 요소)에 대한 포인터가

T *ptr; 
T array[/*some size*/]; 
ptr = &array[n]; 

ptr 경우를 다음 ptr + iarray[n + i]에 대한 포인터입니다 ((n + i) 번째 요소).

은의 당신의 코드를 살펴 보자 : 당신이 그것에 32을 추가 한 후, basepointer(int*)을 캐스팅하고 여기에

*((int*)basepointer+32) = 455; 

. 그러면 basepointer 뒤에 32 번째 주소 (int)가 표시됩니다. 플랫폼이 4 바이트 정수를 사용하는 경우 실제 오프셋은 32 * 4 = 128 바이트입니다. 이곳에 455을 저장합니다.

그런 다음 당신은 basepointervoid * 때문에이 기술적으로 유효하지 않은 번호 및 void 더 크기가 없기 때문에 당신이 void의 관점에서 연산을 수행 할 수 없습니다

void *p = basepointer + 32; 

을한다. 확장 기능으로 gcc는 이것을 지원하며 void은 크기가 1 인 것처럼 가장합니다. (하지만 당신은 정말이에 의존해서는 안 : 캐스트를 unsigned char *에 주소 지정의 바이트합니다.) basepointer32 오프셋에서

지금 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 
0

무효 포인터 연산은 C/C++에서 불법 아마 코드가 작동을 만들기 위해, GCC는 확장으로 그것을 할 수 있습니다. 포인터 연산이 유형의 크기에 상대적으로 계산되기 때문에

void *p = basepointer + 32; 

void *p = basepointer + 32 * sizeof(int); 

에 :

당신이 줄을 수정해야합니다. 예

:

sizeof (int) = 4sizeof(short) = 2

int *p 경우 갖는다 3000
short *sp의 주소 가지고 다음 4000

p + 3 = p + 3 * sizeof(int) = 3012
sp + 3 = sp + 3 *sizeof(short) = 4006

0 어드레스

void의 경우 컴파일러에서 허용하는 경우 1입니다.