2016-12-06 3 views
-1

내가 포인터 char* ptr 할당 된 메모리 및 ptr 메모리가 해제 된 후 arr 어떻게됩니까 다른 포인터 char* arr = ptr상태 메모리가 할당이 해제 된 경우는

을 말해봐.

이 기능은하자 :

char* foo() 
{ 
    char* ptr = new char [100]; 
    char* arr = ptr; 
    delete [] ptr; 
    return arr; 
} 

내가이 값을 반환 할 수 있습니까?

컴파일 타임/런타임 오류가 발생합니까? 또는 다른 건. 함수가 내가 이전의 출력에서 ​​변화가 없을 것입니다하지만, 어떤 변화가있을 것이라고 생각

char* foo() 
{ 
    char* ptr = new char [100]; 
    char* arr = ptr; 
    delete [] arr; 
    return ptr; 
} 

인 경우

또는 어떤 일이 일어날 것 ?? 내가 수업을

class Pointer 
{ 
    public: 
    char* ptr; 
    Pointer() 
    { 
     ptr= new char [100]; 
    } 
    ~Pointer() 
    { 
     delete [] ptr; 
    } 
}; 

을 가지고 작동하는 경우

은 어떻게 될까

Pointer foo() 
{ 
    Pointer ptr; 
    ptr.ptr[0]='l'; 
    return ptr; 
} 

늘 소멸자 함수의 끝에서 호출과 허상 포인터 Pointer::ptr을 만들 수 ??

+0

"이 반환 값을 사용할 수 있습니까?" 당신은 할 수 있지만 그것은 똑똑하지 않을 수 있습니다, 그것은 매달려 포인터가 될 수 있습니다. null 반환 값을 기대하는 경우 null 또는 null'arr' 만 반환하면됩니다. – George

+0

arr이 쓰레기를 가리 킵니다. 그것을 반환하지 마십시오. – AndyG

+1

나는 당신이 틀린 질문을하고 있다고 생각합니다. 전혀 'arr'이 발생하지 않습니다. 또는 그 문제에 대한'ptr'. – juanchopanza

답변

4

이 반환 값을 사용할 수 있습니까 ??

"사용"할 수 있지만 참조 할 수는 없습니다. 당신은, 예를 들어, (그러나 데이터 뾰족한-에!) 포인터 값을 출력 할 수 있습니다 : 값이 "사용"할 수 있지만

std::cout << (intptr_t)foo() << std::endl; // OK 
std::cout << foo(); // WRONG: this dereferences the pointer! 

그래서, 그것은 더 이상 char에 대한 포인터로 정말 유용하지 않습니다.

또는 어떤 함수가 있다면 [...]

두 함수가 같은 의미가 일어날 것입니다. 괜찮은 컴파일러에서는 컴파일 할 때 모두 yield identical machine code을 기대해야합니다.

메모리가 할당 해제 된 후 ptr 후에 arr은 어떻게됩니까?

아무런 변화가 없습니다. 값은 변경되지 않습니다. 그러나 pointed-to 객체는 할당 해제 되었기 때문에 이제는 매달린 포인터가됩니다. 따라서 아무 것도 사용할 수 없습니다. 그렇게하면 정의되지 않은 동작이 발생합니다. 정의되지 않은 동작은 아무 일도 발생할 수 없음을 의미합니다. 여기에는 아무 일도 일어나지 않습니다 (모든 것이 "OK"로 나타남). 또는 하드 드라이브를 포맷하십시오.

많은 상황에 집을 지은 경우와 같은 상황입니다. 친구에게 Arr GPS 좌표를 알려주세요. 그러나 그 사이에 이사를 결정했습니다. 그러나 친구 Arr은 아직 이전 좌표계를 가지고 있습니다. 이제 Arr을 사용하기로 결정했습니다. 몇 가지 결과가있을 수 있습니다.몇 가지를 나열하겠습니다 :

  1. 한 시간 전에 이사 왔습니다. 모든 것은 여전히 ​​동일합니다. Arr이 들렀다가 오래된 집 사진을 찍고 떠났습니다.

    이것은 일치 때문에, 지적 메모리가 여전히 사용 가능한 내용을 포함하고있는 경우에 해당한다. 너는 여전히 버그가 있지만 우연은 그것을 숨 깁니다.

  2. 당신은 이사 갔지만 그 다음날 도시는 제방을 크게 짓고 큰 콘도 건물을 짓기로 결정했습니다. 친구가 작은 집을 기대하며 큰 콘도가 고층으로 쳐져 완전히 엉망이 된 것을 알게됩니다.

    이것은 메모리가 재사용되고 매달린 포인터 역 참조가 이어지는 경우에 해당합니다. 이로 인해 CPU가 예외를 발생시키는 지 여부는 이전에 어떤 종류의 객체가 존재했는지에 따라 다릅니다.

  3. 당신은 이사 왔지만 지진이 있었고 현재 호수가 있습니다. 친구가 쓰러져 익사합니다.

    이것은 무료 저장소의 일부였던 가상 메모리의 현재 중복 된 부분이 매핑 해제 된 경우에 해당합니다. 페이지 오류가 발생합니다.

    메모리 관리자 런타임은 포인터가 가리키는 주소 공간을 백업하는 데 사용한 페이지를 할당 취소 할 수 있습니다. 종종 C++ 프로그램은 가상 메모리 머신에서 실행된다는 것을 상기하십시오. 프로그램이 보는 주소 공간은 가상 주소 공간입니다. 주어진 가상 주소 공간 페이지를 뒷받침하는 물리적 메모리 페이지가없고 해당 페이지에 대한 파일이나 다른 백업이없는 경우 사용자 영역으로 전파되는 페이지 오류가 발생하고 처리되지 않은 경우 프로세스가 종료됩니다 (기본적으로) .

+0

다른 곳을 가리 키거나'nullptr '로 설정할 수 있습니다. – juanchopanza

+0

나는 참고 1 & 2를 이해하지만 3 – WARhead

+0

도 시간 여행을 통해 많은 즐거움을 만들 수 있습니다. 특정 플랫폼은 위반을 일으킨 페이지의 페이징 된 버전을 다시 매핑하여 액세스 위반을 처리 할 수 ​​있습니다. 이로 인해 프로그램 인식없이 오래된 데이터가 발생할 수 있습니다. 짧은 이야기 : 정의되지 않은 동작은 정의되지 않았으며 어떠한 비용으로도 피해야합니다. – Mgetz

0

코드에서 arr은 할당되지 않은 메모리를 가리 킵니다. 따라서 작업을 시도하면 절대적으로 임의의 데이터가 포함됩니다.

+0

그건 사실이 아니에요. 사실이 아닙니다. 임베디드 프로그래밍 같은 것에 유용 할 수 있습니다. – George

+0

임베디드 프로그래밍은 목표가 끝난 후 포인터가 가리키는 것과 같은 간단한 질문을 요구하는 사람을 괴롭히지 않습니다 ... –

0

한 번 임베디드 시스템에서 작업했는데, 때때로 운이 좋으면 시스템이 고장 났을 때 올바른 시간 (삭제와 관련하여) 근처에 디버거가 연결되어있었습니다. 코드는 C++이고 디버거는 gdb, vxWorks는 임베디드 시스템 도구 모음입니다.

내가 검사 한 코드는 귀하의 질문과 몇 가지면에서 유사합니다. 본질적으로 삭제 후 포인터의 참조가 발생했습니다.

... 
    char* ptr = new char [100]; 
    delete [] ptr; 

    // more stuff that did not affect what ptr pointed to 

    // about 5 to 9 lines later 
    char retVal = ptr[x]; // <<< invalid access crash 
... 

크래시가 ptr [x]가 유효하지 않음을 나타냅니다.

임베디드 시스템 (vxWorks)에는 ptr이 실제로는 더 이상 컨텍스트에 있지 않았고 해당 작업에서 매핑되지 않았 음을 확인하는 기술이 있습니다.

(성능 때문에) 비정상적인 것으로 추측 하겠지만, 삭제는 동적 메모리에서 블록을 해제 할뿐만 아니라 스레드 메모리 공간에서 메모리 블록을 해제하여 주소가 유효하지 않게 만들고 버스 오류가 발생합니다.

Linux에서 비슷한 정보를 확인하는 방법을 모르겠습니다.

PTR 메모리 할당이 해제 된 후, 언 어떻게됩니까

?

자동 변수는 삭제의 영향을받지 않습니다.


나는이 값을 반환 할 수 있습니까?

동작이 정의되지 않았습니다 (예 : UB). 그렇게하지 않는 것이 좋습니다.


는 어떤 컴파일 타임/런타임 오류가 발생할 것인가? 아니면 다른 것.

UB는 다른 일이 발생할 수 있음을 의미합니다.

+0

질문을 다시 입력하십시오. – WARhead