2016-07-27 4 views
2

C++ 또는 C에서 포인터가 메모리 경계를 벗어나는 값으로 설정되면 어떻게됩니까? 다음과 같은 코드가 있습니다.포인터가 너무 크면 어떻게됩니까?

int* ptr = 0; 
while (true) { 
    ptr += 1; // eventually this will go out of bounds of the memory ... unless there is an overflow. 
    *ptr = 10; // just give it a value, why not? 
} 

어떻게 될까요? 포인터가 범위를 벗어나면 16 바이트 메모리를 가정 해 봅시다 - 단지 0xF에서 0x0로 전환하는 것입니까? 카운트 업을 계속하고 컴퓨터가 *ptr = 10; 회선과 충돌합니까?

나는 바보가 아니기 때문에 노력하고 있지만 매우 궁금합니다.

+2

'시도하기에 어리석지는 않지만 매우 궁금합니다. '- 그냥 시도해보십시오. 이것은 적절한 대답을 대체하지는 않지만, 주요 OS에서 실행중인 경우 응용 프로그램 외부에서 아무런 해를 끼치 지 않을 것입니다. – Thebluefish

+1

예, 포인터는 단순한 값 컨테이너가 아닙니다. 단지 뒤집을 것입니다. 반면 몸의 두 번째 라인은 100 % UB 기회를가집니다. –

+4

정의되지 않은 동작 ahoy – user975989

답변

10

정의되지 않은 동작입니다.

사실 포인터가 원래 가리키는 대상의 끝을지나 한 요소보다 많은 위치를 가리 키도록 포인터를 증가 시키면 정의되지 않은 동작이 발생합니다. (당신은 객체의 끝을 지나서 포인터를 만들 수 있지만 그 이상의 포인터는 만들 수 없습니다.) (문제의 객체는 하나의 요소를 가진 배열로 취급되는 배열이 아닌 객체입니다.)

이것은 언어 표준이 어떤 일이 발생할 수 있는지에 대해 아무것도 말하지 않음을 의미합니다. 그것은 "작동"할 수도 있고, 프로그램을 중단시킬 수도 있으며, 프로그램이 생성 할 수있는 증상을 유발할 수도 있습니다.

실제로이 동작은 시스템마다 다를 수 있습니다. 포인터를 증가 시키면 부호없는 정수가 증가하는 것과 같은 일을 할 가능성이 높습니다. 보이는 문제를 일으키지 않고 값을 업데이트하십시오. 포인터를 역 참조하려고하면 시스템이 메모리를 관리하는 방법에 따라 결과가 달라집니다.

결론 : 정의되지 않은 동작은 정의되지 않았습니다.

+6

포인터를 객체를 지나서 절대적으로 가리킬 수 있습니다. – EOF

+2

@EOF 더 구체적으로는 객체의 "단지"과거 (끝)이지만. –

+2

@ EOF : 맞아. 내 말씨가 정확하지 못한 점은 어색했다. 나는 그것을 고쳤다. –

1

포인터는 객체 또는 "1 패스"에만 유효합니다.

int x; 
int *p = &x; 
p++; 
p++; // invalid 
int y[5]; 
p = &y[4]; 
p = &y[5]; 
p = &y[6]; // invalid 

포인터에 널 포인터 값이 할당 될 수 있습니다.

p = NULL; 

포인터는 기능을 나타낼 수 있습니다.

그게 전부입니다. 다른 값에 대한 포인터를 할당하면 정의되지 않은 동작 (UB)과 같은 것입니다 : (new 또는 malloc 등으로) 당신에게 할당 된 어떤 외부 메모리 액세스

int* ptr = 0; 
ptr += 1; // UB (NULL is not a pointer to a valid object, so "1 pass" is UB) 
2

가 C에 정의되지 않은 동작입니다 ++, 아무 것도 잘 될 것이라고 기대하지 마십시오.

실제로 실제 한계 밖의 포인터를 증가시키는 것은 플랫폼에 의해 정의되며, 대부분의 플랫폼에서 결국 롤오버됩니다. 액세스하면 충돌이 발생할 수 있습니다.

대부분의 최신 OS에서는 프로세스가 할당 된 바깥의 메모리를 읽거나 쓰려고 시도하여 액세스 위반 또는 세그먼트 화 오류가 발생합니다.

1

C/C++ 언어는 기존 시스템/시스템에는 정의되어 있지 않지만 추상 블랙 박스는 (현실을 무시하지는 않지만) 정의되어 있습니다.정의되지 않은 동작 (일부 기존 시스템/기계가 예상 한대로 작동 할 수도 있음)을 묻습니다.

0

포인터는 unsigned long과 매우 유사하게 동작합니다 (주로/내 시스템에만 해당).

int main(){ 
    char* p = NULL; 
    printf("%p\n", p); 
    printf("%p\n", --p); 
} 

출력 :

(nil) 
0xffffffffffffffff 

하지만 이국적인 물건의 모든 종류의 생각은 이론적으로 발생할 수 있습니다.

0

IMO, 포인터는 아무 문제가 없습니다. 포인터를 저장하면 아무 일도 일어나지 않지만 역 참조를 시도하거나 액세스 할 때 코드가 액세스 위반으로 끝나고 충돌이 발생합니다. 프로그램. 또는 유효한 포인터 인 경우 다른 데이터를 수정합니다. '

관련 문제