2012-05-26 6 views
6

다른 사람의 코드를 디버깅 할 때 포인터가 삭제되면 어떻게 찾을 수 있습니까?포인터가 삭제 된시기를 확인하는 방법은 무엇입니까?

+11

단순 : 할 수 없습니다. –

+3

삭제 된 포인터가 아니며 해당 포인터가 가리키는 메모리 영역 (또는 데이터 객체)입니다. 그러나 http://valgrind.org/ –

+0

을 참조하십시오. 일반적인 경우 Valgrind/Purify/Insure ++와 같은 도구를 사용하여 이중 삭제 및 누수 같은 버그를 찾는 데 도움이되는 경우도 있습니다. –

답변

5

1)

디버거를 사용하십시오. 하나를 삭제하십시오. 일반적으로 당신은

과거 포인터가 조사 포인터

2)

한 유사한 접근과 같은 값을 가지고있는 상태로 중단 점을 설정 포인터를 전달 일부 "무료"기능에 결국 "delete"메소드를 오버라이드하고 해당 포인터를 검사하는 것입니다.

3)

포인터가 소멸자가있는 개체를 가리키는 경우. 소멸자에 중단 점을 놓습니다. 먼저 소멸자를 추가 할 수 있습니다 (가능한 경우 외부 코드로 항상 가능하며 자체 코드에서 항상 가능)

+0

답장을 보내 주셔서 감사합니다. 나는 당신의 의견을 이해하려고 노력할 것입니다. 하지만 C++ 프로그래밍 경험은 "Hello World"로 제한됩니다. 2-3 일 내에 작업을 완료 할 수있는 간단한 솔루션을 찾을 수 있기를 바랍니다. 필자는 main.cpp에서 'char * foo = ""'코드가 세그먼트 오류없이 실행될 수있는 것으로 정의 된 포인터에 대해'delete '명령을 주석 처리합니다. 그러나 나는 왜 그 이유를 찾고 싶습니다. –

+0

'char * foo = ""'와 같은 상수에 의해 생성 된 포인터는 ** delete **를 사용하면 안됩니다. 객체가 ** new ** –

0

GDB watchpoint은 어떻습니까? 문제의 포인터에 감시 점을 설정하고 프로그램이 해당 지시를 삭제할 때 참조 할 수 있습니다.

+0

에 의해 생성 된 경우에만 ** delete **를 사용하십시오. –

+0

많은 아키텍처가 읽기 감시 점을 지원합니다. 포인터에 읽기 감시 점을 설정할 수 없습니까? –

0

포인터가 가리키는 메모리를 참조 할 수 없습니다. 그러나 dangling 포인터에 문제가있는 경우 boost :: shared_ptr로 모든 원시 포인터를 바꾸고 모든 free 및 delete 항목을 제거하십시오. 삭제 또는 무료 키워드를 절대로 사용하지 마십시오. 스마트 포인터 바위!

+0

나는 사람들이 공유 포인터에 대한 원시 포인터를 교체하는 것만 큼 쉽다는 것을 알았지 만 그것은 사실이 아닙니다. 공유 포인터 복사 속도가 느립니다! 당신이 그들을 사용하는 경우 가능한 한 참조로 통과를 사용하여 가능한 한 적은 복사본을 만들 있는지 확인해야합니다. –

+0

@ChrisHayden : 대부분의 사람들은 공유 포인터가 필요하지 않습니다. 고유 포인터가 좋습니다. – Puppy

-1

수 없습니다. 스마트 포인터를 사용하고 걱정하지 마십시오.

+2

타임 머신을 가지고있는 경우에만 '다른 사람에게'스마트 포인터로 코드를 작성하도록 알려줄 수 있습니다. 실제 프로그래밍의 대부분은 기존 코드에 대한 일부 작업을 수행합니다. –

+4

또는 ... 문제가되는 코드를 리펙토링합니다. 오래된 불량 코드로 인한 메모리 오류를 무한히 낭비하는 시간을 낭비하는 것은 리팩토링하여 발생하지 않는 것이 좋습니다. 엄청난 노력 끝에 모든 버그를 제거하는 데 성공하더라도 사람들이 새로운 버그를 도입하는 것을 막을 수는 없습니다. 유일한 일반적인 해결책은 리팩터링하는 것입니다. – Puppy

+0

저는 ASIC 디자이너입니다. "hello world"경험으로 5 년이 넘는 코드를 다시 쓸 수는 없습니다. –

3

해당 유형의 소멸자에 조건부 중단 점을 설정하십시오. . 조건이 2010 비주얼 C++ Express에서, 당신은 예 관심있는 객체에 그 this 포인트하자 : 내가 처음 세 new 표현 이후에 실행 위의 그림에 대한

enter image description here

, 다음 언급 주소를 b 개체의 주소로 변경 한 다음 this이 해당 주소 여야한다는 중단 점 조건으로 사용됩니다.

세부 정보 다른 디버거와 함께이 작업을 수행하는 방법은 디버거에 따라 다릅니다. 디버거 설명서를 참조하십시오.

+0

답장을 보내 주셔서 감사합니다. 그러나 나는 리눅스에서 일하고 있으며, C++ 코드는 makefile에 의해 컴파일되고 실행된다. 코드에는 생성자/소멸자가 없습니다. 포인터는'char * foo = ""'로 정의되고'delete [] foo'로 삭제됩니다. 주석 행을 삭제하면 모든 것이 잘 보입니다. 그래서 포인터 foo가 삭제 된 곳에서 코드를 찾으려고합니다. –

+0

당신이 지금 말한 것이 정확하다면, 문제의 포인터가 리터럴 문자열을 가르키고 있다면, 당신이 삭제 한'delete []'가 문제였습니다. nullpointer의'delete'를 제외하면'new []'에 의해 얻지 못한 포인터를'delete []'하는 것은 UB입니다. 그러나 여러분이 말하는 것은 완전히 정확하지는 않을 것이라고 생각합니다.이 경우 디버깅 대신에'std :: string'을 사용하십시오. –

1

C++에서는 inbuilt 크로스 플랫폼 기능이 없으므로 포인터가 삭제되는지 여부를 알 수 있습니다.

그러나 일부 디버거, 도구 및 언어 자체에서 제공하는 기능을 사용할 수 있습니다. 예를 들어, newdelete 운영자를 전 세계 및/또는 클래스 기반에 오버로드하여 공통 세트 /지도 종류의 참조를 유지할 수 있습니다. 예컨대 : 주기적 염기 나 본 set의 내용이 인쇄되거나 확인 될 수있는 프로그램의 끝에

class X { 
    ... 
    set<void*> m_CurrentAlloc; 

public: 
    void* operator new (size_t SIZE) 
    { 
    ... 
    m_CurrentAlloc.insert(p); 
    return p; 
    } 

    void operator delete (void *p) 
    { 
    m_CurrentAlloc.erase(p); 
    ... 
    } 
}; 

.
이것은 new/delete을 사용하여 메모리 관리를 수행하는 이상적인 상황을위한 해결책이라는 것을 기억하십시오. malloc/free의 믹스가있는 경우 코드에도 다른 개선 사항이 필요합니다.