2013-01-16 2 views
2

나는 하루 종일 코드를 실행하고 있습니다.[]을 (를) 삭제하지 못했습니다. 이유를 찾는 방법은 무엇입니까?

delete [] p 

뒷면 추적 (GDB 사용) :

내가 발견 할
0x00007f4f709f2885 in raise() from /lib64/libc.so.6 
0x00007f4f709f4065 in abort() from /lib64/libc.so.6 
0x00007f4f70a2f7a7 in __libc_message() from /lib64/libc.so.6 
0x00007f4f70a350c6 in malloc_printerr() from /lib64/libc.so.6 

무슨 일이 실패 삭제 원인 : 일부 포인터를 해제하려고 할 때 는 일주일에 한 번, 그것은 충돌 삭제 중복 또는 다른 것. 어떻게 할 수 있습니까?

+3

사람들이 당신을 도울 수 있기를 원하면 첫 번째 단계는 실제로 코드를 게시하는 것입니다. 일반적인 "어떻게 이런 종류의 문제를 디버깅합니까?"라는 조언은 당신이 원하는 것입니다. 삭제가 호출 될 때마다 로깅을 시작합니다. 누가 언제, 왜 호출했는지 기록합니다. 그것을 통해 빗질을 시작하여 버그의 출처를 찾으십시오. – Oren

+0

더 많은 코드를 보여줘야합니다. valgrind를 사용해 볼 수도 있습니다. – goji

+0

버그를 찾기 위해 valgrind를 통해 프로그램을 실행하는 것이 좋습니다. – Grizzly

답변

1

좋은 단위 테스트를 작성하고 valgrind를 사용하여 실행하고 버그를 잡을 수 있기를 바랍니다.

그 밖의 경우에는 코드를보고 버그를 검색 할 수 있습니다 (예 : "Good Clues, Easy Bugs" article은 디버그 기술을 설명합니다).

2

우선, 백 트레이스에는 malloc_printerr이라는 호출이 포함되어 있습니다. 이 함수는 표준 오류의 이유를 기록 할 것이므로 캡처 한 것을 잊지 마십시오!

새/삭제 유형, 이중 삭제 또는 유효하지 않은 포인터가 모두 일치하는지 여부에 관계없이 실제 버그는 실제로 삭제를 감지하기 전에 발생합니다. 그래서 gdb는별로 유용하지 않을 것입니다. 당신은 관련 포인터에 일어나는 일들을 기록하고 그것이 잘못되었을 때 파헤쳐 야 할 것입니다.

  • 잘못된 포인터 일 경우 초기화되지 않은 메모리 또는 버퍼 오버런으로 덮어 쓰게됩니다. 모든 오브젝트가 관련된 포인터를 제로로 만드는 올바른 생성자를 가지고 있는지 검토하십시오. 어느 쪽의 문제도 valgrind으로 잡을 수 있으며, 버퍼 오버런은 DUMA library 또는 mudflap (gcc와 함께 제공됨)을 사용하여 적은 오버 헤드로 (덜 정밀도로) 잡을 수 있습니다.
  • 두 번 삭제하는 경우 소멸자가있는 경우를 제외하고는 삭제 한 후에 관련된 포인터를 모두 제로로 검토하십시오 (소멸자에서 삭제하는 경우 생성자에서 초기화했는지 확인하십시오). 관련 포인터에 대한 모든 작업에 대한 로그 메시지를 추가하고 충돌이 발생하면 포인터가 부활 한 것으로 보이는 로그를 추적합니다. 당신은 또한 무효 포인터에 대해 그렇게하려고 할 수 있습니다.
  • []이 맞지 않으면 []으로 할당 할 때 항상 []으로 삭제하고 항상 완전한 유형을 삭제해야합니다 (C++은 불완전한 유형 삭제 및 정의되지 않은 동작을 허용 함).
  • 위의 것들 중 하나는 관련된 포인터를 가지고있는 객체의 소멸자를 적절하게 호출하지 못하는 부차적 인 결과 일 수도 있습니다. 소멸자를 호출하지 못하면 잘못된 유형의 포인터를 삭제하거나, 불완전한 유형의 포인터를 삭제하거나, 새로 불일치가 발생하여 []이 일치하지 않을 수 있습니다. 검토 외에도 관계가있을 수있는 생성자와 소멸자에 로그를 추가하고 올바르게 일치하는 로그를 확인하십시오.

실제로 항목을 일치시킬 수 있도록 항상 포인터 값을 기록하는 것을 잊지 마십시오. 로그 분석을위한 스크립트를 작성해야 할 수도 있습니다 (일치하지 않는 항목을 찾으십시오). 그리고 충분한 공간을 확보하십시오. 이 방법으로 많은 giga 바이트를 생성하는 것이 다소 쉽습니다.

용의자가 몇 가지 작업을 제한하면 로그에 백 트레이스를 작성해야 할 수 있습니다. backtrace(3) 라이브러리 함수 또는 libunwind을보십시오.

관련 문제