2012-10-07 1 views
2

는 :개체의 동적 배열에서 delete []를 호출해도 메모리가 할당 해제되지 않습니다? 다음 코드에서

int main(int argc,char * argv[]){ 
    int * ptr; 
    ptr = 0; // tried also with NULL , nothing changes 
    ptr = new int[10]; // allocating 10 integers 
    ptr[2] = 5; 
    ptr[15] = 15; // this should cause error (seg fault) - but it doesn't 

    cout << ptr[2] << endl; 
    cout << ptr[15] << endl; // no error here 

    delete [] ptr; 

    cout << ptr[2] << endl; // prints the value 5 
    cout << ptr[15] << endl; // prints the value 15 
} 

실행의 결과는 : 만 할당하고있어 경우

  1. 5   
    15   
    5   
    15   
    
    어떻게 인덱스 번호 (15)를 가진 요소가 존재할 수 10?
  2. 왜 전체 배열을 할당 해제 한 후에도 포인터에 값이 남아 있습니까?

    int * ptr; 
    ptr = 0; 
    ptr = new int; 
    *ptr = 5; 
    cout << *ptr << endl; 
    delete ptr ; 
    cout << *ptr << endl; 
    

    결과는 정상입니다 : GCC 4.7.2과에 GCC 4.1.2로

    5   
    0   
    

    을 테스트

는이 같은 하나의 할당으로 삭제 시도 fedora 17과 다른 플랫폼 (SLC5 - Red Hat 기반 리눅스)을 컴파일러에 의존하지 않도록합니다. 여기서 내가 뭘 잘못하고 있니?

+0

제 생각에는 허용 된 대답 [읽어야합니다] (http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) (질문이 다릅니다. 조금 있지만 동일한 인수가 적용될 수 있습니다.) – Lol4t0

답변

9
  1. 의도 한 크기의 배열을 초과하는 요소가 존재합니다. 메모리가 존재하기 때문입니다. 그것으로 무엇이든하는 것은 불법이고 어둠은 알려지지 않습니다.

  2. 할당 해제는 메모리가 더 이상 할당되지 않는다는 것을 의미합니다. 누군가가 거기에 가서 청소했음을 의미하지는 않습니다. 하지만 거기에 남은 것을 접근하는 것은 불법이며 어둠을 알 수 없습니다.

+0

'어두운 알 수 없음'은 실제로 C++ 표준 표현에 명시 적으로 나타나는 '정의되지 않은 동작'을 의미한다고 추가하겠습니다. :) – vines

+1

예 ;-) 나는 "정의되지 않은 동작"이라고 말하고 싶습니다. 정의되지 않은 것이 정의를 향상시켜 알기 쉽게 알려주지 않기 때문입니다 .-- 나는 단지 진부한 말씨를 사용하는 것을 좋아합니다. 사람들이 일반적인 개념을 재 해석하게 만듭니다. . –

+0

까지 1.이 점은 저에게 효과적입니다. 요점은 내 '사용자'가 within -> getElement (int elementNum)에서 96의 숫자를 초과해서는 안되며, 97에서 시도하는 동안 예상치 못한 값을 반환하고 있다는 것입니다. 그래서 지금 나는 사용자에게 '불가능하게'해야한다고 확신합니다. 2.이 과정에서 먹는 메모리에 대해서만 신경을 쓰고 있기 때문에 이것은 저에게 효과적입니다. 나는 그것을 청소하지 않을까 걱정되었다. –

1

어레이에 속하지 않는 메모리에 액세스하고 있습니다. 그것은 순수한 행운 때문에 일합니다. 프로그램이 충돌하지 않는다면, 이는 자신의 응용 프로그램에 속한 메모리의 일부를 덮어 쓰고 있다는 뜻이므로 어딘가에 무언가를 망칠 수 있으며 더 이상 프로그램이 올바르게 작동한다는 것을 보장 할 수 없습니다.

대부분 다른 응용 프로그램의 메모리에 액세스하기 때문에 세그먼트 오류가 발생합니다. 이번에, 당신은 단지 '행운아'입니다. 또는 프로그램이 메모리 오류를 가지고 있다는 것을 즉시 실행에서 알 수 없으므로 불운하다고 부릅니다.

+0

감사합니다. 나는 '예상 된 seg fault'를 얻기 위해 메모리 사용 프로그램으로 시스템을 '로드'하려고 시도 할 것이다. 나는 내 기억을 예상대로 청소하지 않을까 봐 걱정했다. –

1

삭제 된 포인터를 역 참조하는 것은 C++ 표준에 정의 된대로 정의되지 않은 동작입니다. 그리고 그것은 단지 - 정의되지 않은 동작입니다. 당신은 충돌 할 수 있었고, 0을 얻을 수 있었고, 이전에 있었던 것을 얻을 수있었습니다. 또는 42. 정의에 의해 그 시점에서 "정상적인"행동은 없었습니다.