2010-12-01 4 views
3

위의 프로그램을 gcc 컴파일러 (www.codepad.org)에서 실행하면 으로 출력됩니다. 허용되지 않는 시스템 호출 : SYS_socketcall 이 오류/출력이 왜 발생하는지 명확히 알 수 있습니까?포인터 할당 문제

int main() { 
    int i=8; 
    int *p=&i; 
    printf("\n%d",*p); 
    *++p=2; 
    printf("\n%d",i); 
    printf("\n%d",*p); 
    printf("\n%d",*(&i+1)); 
    return 0; 
} 

제가 관찰 한 바에는 * ++ p = 2를 실행 한 후에 액세스 할 수 없게되는 이유는 무엇입니까?

답변

5

*p = &i을 수행 할 때 p은 단일 정수 i을 가리 킵니다. ++pp을 "다음"정수를 가리 키도록 증가하지만 i은 배열이 아니므로 결과가 정의되지 않습니다.

+0

올바른 설명. 감사합니다. – hari

+0

다음 코드는 정상적으로 실행됩니다 : INT의 main() { INT의 I = 8; INT의 *를 P = 난; 의 printf ("\ n을 % d에"* P) * ++ p = 2; //의 printf ("\ n 개의 % d ", i); printf ("\ n % d ", * p); // printf ("\ n % d", * (&i+1)); return 0; } 이것은 * ++ p = 2로 인해 문제가 있다는 것을 의미합니다. 할당되지 않은 메모리에 액세스 했음에도 불구하고 문제가 없습니다. * ++ p = 2 p는 값 2 인 위치를 가리 킵니다. 그러나 혼란은 i.SO의 가치를 변경시키지 못하는 이유는 무엇입니까? – sudhansu

+0

i는 배열이 아니지만 * ++ p = 2.i에 4 바이트 만 할당 된 후 값이 변경됩니다 .4 바이트 만 후 위치를 가리 킵니다. 왜 내가 액세스 할 수 없습니까? – sudhansu

2

관찰중인 것은 정의되지 않은 동작입니다. 특히 i은 적어도 두 개의 멤버가있는 배열이 아니므로 p*++p=2에 역 참조 할 수 없습니다. 실제로 프로그램은 주소가 &i + sizeof(int) 인 메모리에 쓰려고 할 가능성이 큽니다.

1

정의되지 않은 동작을 스택의 정의되지 않은 영역에 쓰면 이 호출됩니다. codepad.org는 허용되지 않는 행위를 시도하는 프로그램에 대한 보호를받으며 정의되지 않은 행동 프로그램이이를 유발 한 것으로 보입니다.

자신의 컴퓨터에서 그렇게하려고하면 프로그램이 세그먼트 화 오류 또는 버스 오류와 같은 다른 방식으로 충돌을 일으킬 수 있습니다.

1

발현 *++p 제 포인터 이동 p 앞으로 한 int 가리 (포인터가 무효가되고, 즉 예), 생성 된 포인터를 역 참조함으로써 잘못된 메모리에 쓰는,이 숫자 2를 저장하려고.

*p = 2 또는 (*p)++을 의미했을 수 있습니다.

+0

다음 코드는 정상적으로 실행됩니다. int main() { int i = 8; int * p = & i; printf ("\ n % d", * p); * ++ p = 2; // printf ("\ n % d", i); printf ("\ n % d", * p); //의 printf ("\ n을 % d에"* (&i+1)); 복귀 0; } 이 문제 때문에 * ++ p = 2.Though i가 액세스 한 할당되지 않은 메모리 NT 수단, 그 문제가 NT. AFTER * ++ p = 2 p는 값 2 인 위치를 가리 킵니다. 그러나 혼란은 iOS의 값을 변경하지 못합니다. – sudhansu

0

코드가 소유하지 않은 메모리에 액세스하며 그 결과는 정의되지 않습니다.

모든 코드는 &p에서이 현재 기록 된대로 할 권리 읽고 &i에서 크기 sizeof(int)의 영역 메모리에서 작성하는 것입니다 및 크기 sizeof(int*)의 다른있다.

다음 행은 모두 데이터를 읽거나 쓸 수있는 범위 밖의 메모리 주소를 사용하여 이러한 제약 조건을 위반합니다.

*++p=2; 

printf("\n%d",*p); 
printf("\n%d",*(&i+1)); 
0

은 운영자 ++는 인수를 수정, 그래서 라인 *++p=2; 아마 call frame 증가 포인터 p를 정의하는 스택에 위치 2를 할당합니다. 일단 콜 프레임을 엉망으로 만든 - 모든 베팅은 꺼져 있습니다 - 당신은 부패한 상태에 처하게됩니다.