2017-12-21 33 views
1

코드를 다음과 같이 코딩했는데 새 주소에 값을 할당 할 수 있었지만 값을 증가시킨 후이 값을 인쇄 할 수 없었습니다. run time error 또한 값을 위치를 가리키는이 포인터, 포인터 값이 14로 변경되었습니다. 누구나 무슨 일이 일어나고 있는지 알 수 있습니까?C 프로그래밍, 포인터 런타임 오류

값 자체를 위치 자체에 할당 한 후 포인터 값 자체가 14로 변경된 이유는 무엇입니까?

포인터 값을 늘린 후에도 오류가 발생하지 않았습니다!

#include <stdio.h> 
int main() 
{ 
    int x = 10; 
    int *ptr = &x; 
    printf("%x\n",ptr);    // ptr value 
    ptr++;       //No ERROR !! 
    printf("%x\n",ptr);    //ptr value +4 bytes no error!!! 
    *ptr = 20; 
    printf("%x\n",ptr);    //ptr=14 
    printf("%x\n",*ptr); // run time error happens here only 
    return 0; 
} 
+1

일단 포인터를 움직이면 더 이상 유효한 위치를 가리키고 있지 않습니다. UB. –

+0

** 오류 없음 **, 정의되지 않은 동작 **이 있습니다. **. 귀하의 코드는 정의되지 않은 동작이있는 6 개의 위치가 있습니다. –

답변

0

정의되지 않습니다. 이 경우 x은 크기 1의 배열로 처리되고 포인터는 배열의 끝을지나 한 요소를 가리킬 수 있으므로 허용됩니다. 나중에 문제없이 해당 포인터의 값을 인쇄 할 수도 있습니다.

그러나 할 수없는 일은 끝에있는 한 요소에 대한 포인터를 참조 해제하는 것입니다. 그러면 undefined behavior이 호출됩니다. 이 경우 예기치 않은 값과 후속 충돌이있는 포인터로 나타나는 동작입니다.

그런데 아마 일어난 일이 있습니다.

ptr은 대부분 바로 메모리에 x 다음에 위치, 그래서 ptr++을 수행 한 후, ptr 자체를 가리키는했다. 따라서 *ptr = 20;ptr을 20으로 설정하는 효과가있었습니다. 인쇄 된 값 14는 10 진수로 20 진수와 같습니다. 이것은 인쇄 된 값을 설명합니다.

그런 다음 *ptr을 인쇄하려고했는데이 경우 "int 값을 주소 0x14에 인쇄"합니다. 그럴 가능성이있는 주소는 유효하지 않으므로 읽으려고하면 충돌이 발생합니다.

그러나이 동작에 의존 할 수는 없습니다.printf을 추가하거나 다른 최적화 설정으로 컴파일하면 관찰 된 동작이 변경됩니다.

2

이것은 정의되지 않은 동작입니다. 포인터 변수를 증가 시켰을 때 변수 x (시스템에서 4 바이트 지난)을 가리키고있었습니다. 그러나 그런 다음 그것을 역 참조하십시오. 우선 변경 한 메모리는 할당되지 않습니다. 또한 이미 할당 된 위치가 아닙니다 (배열의 일부 등). 그것에 액세스하려면 정의되지 않은 동작입니다.

다시 가능한 모든 주소에 할당 할 수 있습니다. 그러나 그것이 참조하는 메모리 주소가 유효하지 않은 경우에는 역 참조가 정의되지 않은 동작이됩니다. 6.3.2.3표준

단항 * 조작자로부터

간접 참조를 나타낸다. 피연산자가 함수를 가리키는 경우 결과는 함수 지정자입니다. 개체를 가리키는 경우 결과는 개체를 지정하는 lvalue입니다. 피연산자 의 유형이 ''pointer to type'' 인 경우 결과는 type입니다. 유효하지 않은 값이 포인터에 할당 된 경우 ptr++ 작업을 수행 할 때 단항 * 연산자의 동작은 x 과거 "하나 개의 요소"지적,

+0

포인터에 "주소 값"자체는 무엇입니까? 왜 값을 할당 한 후에 변경 되었습니까? – IDEN

+0

새 값을 할당했기 때문에 할당이 의미하는 것입니다. C는 일반적으로 당신이 illiegal/멍청한 일을하지 못하게하는 저급 언어입니다. –

+0

@LeeDanielCrocker 나는 주소 값 자체를 변경하지 않았다고 믿는다. 포인터가 가리키는 위치에 값을 추가했다.이 값 "20"이 포인터 값 자체에 영향을 미치지 않을 것이라고 생각했는데, 0x14는 포인터의 올바른 값이 아니다. – IDEN