C ++ 코드 / 프로젝트에서 메모리 누수를 찾는 방법은 무엇입니까?
저는 Windows 플랫폼의 C ++ 프로그래머입니다. Visual Studio 2008을 사용하고 있습니다.
나는 보통 메모리 누수로 코드를 작성합니다.
일반적으로 코드를 검사하여 메모리 누수가 발견되지만 번거롭고 항상 좋은 접근 방식은 아닙니다.
유료 메모리 누수 감지 도구를 사용할 수 없기 때문에 메모리 누수를 피하는 가장 좋은 방법을 제안하기를 원했습니다.
- 프로그래머가 메모리 누수를 찾는 방법을 알고 싶습니다.
- 프로그램에 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
명령
필요한 것
- C ++ 능력
- C ++ 컴파일러
- 디버거 및 기타 조사 소프트웨어 도구
1
운영자 기본 사항을 이해하십시오. C ++ 연산자 "new"는 힙 메모리를 할당합니다. "삭제"연산자는 힙 메모리를 비 웁니다. 모든 "신규"에 대해 "삭제"를 사용하여 할당 한 동일한 메모리를 해제해야합니다.
char* str = new char [30]; // Allocate 30 bytes to house a string.
delete [] str; // Clear those 30 bytes and make str point nowhere.
2
삭제 한 경우에만 메모리를 재 할당하십시오. 아래 코드에서 str은 두 번째 할당으로 새 주소를 얻습니다. 첫 번째 주소는 복구 할 수 없을 정도로 손실되었으며, 지정한 30 바이트도 손실되었습니다. 이제는 해제가 불가능하며 메모리 누수가 있습니다.
char* str = new char [30]; // Give str a memory address.
// delete [] str; // Remove the first comment marking in this line to correct.
str = new char [60]; /* Give str another memory address with
the first one gone forever.*/
delete [] str; // This deletes the 60 bytes, not just the first 30.
삼
그 포인터 할당을보십시오. 모든 동적 변수 (힙에 할당 된 메모리)는 포인터와 연관되어야합니다. 동적 변수가 포인터와 연결 해제되면 지울 수 없게됩니다. 다시 말하지만, 메모리 누수가 발생합니다.
char* str1 = new char [30];
char* str2 = new char [40];
strcpy(str1, "Memory leak");
str2 = str1; // Bad! Now the 40 bytes are impossible to free.
delete [] str2; // This deletes the 30 bytes.
delete [] str1; // Possible access violation. What a disaster!
4
로컬 포인터에주의하십시오. 함수에서 선언 한 포인터는 스택에 할당되지만 해당 포인터가 가리키는 동적 변수는 힙에 할당됩니다. 삭제하지 않으면 프로그램이 기능을 종료 한 후에도 유지됩니다.
void Leak(int x){
char* p = new char [x];
// delete [] p; // Remove the first comment marking to correct.
}
5
"삭제"후 대괄호에주의하십시오. 단일 객체를 해제하려면 "삭제"만 사용하십시오. 힙 배열을 해제하려면 대괄호와 함께 "delete"[]를 사용하십시오. 다음과 같이하지 마십시오 :
char* one = new char;
delete [] one; // Wrong
char* many = new char [30];
delete many; // Wrong!
6
누출이 아직 허용 된 경우-일반적으로 deleaker를 사용하여 찾고 있습니다 ( http://deleaker.com ).
감사!
코드에서 일부 기술을 사용하여 메모리 누수를 감지 할 수 있습니다. 감지하는 가장 일반적이고 가장 쉬운 방법은 매크로 말, DEBUG_NEW를 정의하고 같은 미리 정의 된 매크로와 함께 사용된다 __FILE__
및 __LINE__
코드에서 메모리 누수를 찾습니다. 이러한 사전 정의 된 매크로는 파일 및 행 수의 메모리 누수를 알려줍니다.
DEBUG_NEW는 MACRO 일 뿐이며 일반적으로 다음과 같이 정의됩니다.
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
따라서 어디에서나 사용하면 new
프로그램에서 메모리 누수를 찾는 데 사용할 수있는 파일과 줄 번호를 추적 할 수 있습니다.
그리고 __FILE__
, __LINE__
하는 매크로 미리 정의 당신이 그들을 사용하는 경우 각각 파일 이름과 라인 번호로 평가!
다른 흥미로운 매크로와 함께 DEBUG_NEW를 사용하는 기술을 매우 아름답게 설명하는 다음 기사를 읽으십시오.
에서 Wikpedia ,
Debug_new는 C ++에서 메모리 할당 및 할당 취소 호출을 가로 채기 위해 연산자 new 및 operator delete를 오버로드 및 / 또는 재정 의하여 메모리 사용을 위해 프로그램을 디버깅하는 기술을 나타냅니다. DEBUG_NEW라는 매크로를 정의하는 경우가 많으며 new 는 파일 / 라인 정보를 할당 할 때 new (_ FILE _, _ LINE _) 와 같은 형식으로 만듭니다 .Microsoft Visual C ++는이 기술을 Microsoft Foundation 클래스에서 사용합니다. 매크로 재정의를 사용하지 않고 일부 플랫폼에서 파일 / 라인 정보를 계속 표시 할 수 있도록이 방법을 확장 할 수있는 몇 가지 방법이 있습니다. 이 방법에는 많은 고유 한 제한이 있습니다. C ++에만 적용되며 malloc과 같은 C 함수에 의한 메모리 누수를 포착 할 수 없습니다. 그러나 일부 완전한 메모리 디버거 솔루션과 비교할 때 사용이 매우 간단하고 빠를 수도 있습니다.
처음에 메모리 누수가 발생할 위험을 최소화하는 데 도움이되는 잘 알려진 프로그래밍 기술이 있습니다.
- 고유 한 동적 메모리 할당을 수행해야하는 경우 항상 쌍으로 작성
new
하고delete
할당 / 할당 해제 코드를 쌍으로 호출해야합니다. - 가능하면 동적 메모리 할당을 피하십시오. 예를 들어,
vector<T> t
가능한 경우 대신 사용하십시오T* t = new T[size]
- 부스트 스마트 포인터와 같은 "스마트 포인터"사용 ( http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm )
- 내가 개인적으로 좋아하는 것 : 포인터의 소유권 개념을 이해하고 포인터를 사용하는 모든 곳에서 어떤 코드 엔티티가 소유자인지 확인하십시오.
- C ++ 컴파일러가 어떤 생성자 / 할당 연산자를 자동으로 생성하는지, 그리고 포인터를 소유 한 클래스가있는 경우의 의미 또는 소유하지 않은 객체에 대한 포인터가 포함 된 클래스가있는 경우의 의미를 알아 봅니다 .
- Windows 용 디버깅 도구를 다운로드 하십시오 .
gflags
유틸리티를 사용하여 사용자 모드 스택 추적을 켜십시오.UMDH
프로그램 메모리의 여러 스냅 샷을 만드는 데 사용 합니다. 메모리가 할당되기 전에 스냅 샷을 만들고 프로그램에서 메모리가 누수되었다고 생각되는 지점에서 두 번째 스냅 샷을 만듭니다. 프로그램에 일시 중지 또는 프롬프트를 추가UMDH
하여 스냅 샷 을 실행 하고 만들 수있는 기회를 제공 할 수 있습니다 .UMDH
이번에는 두 스냅 샷을 서로 다른 모드로 다시 실행 하십시오. 그런 다음 메모리 누수가 의심되는 호출 스택이 포함 된 보고서를 생성합니다.gflags
완료되면 이전 설정을 복원하십시오 .
UMDH
전체 프로세스에서 메모리 할당을 감시하고 있기 때문에 CRT 디버그 힙보다 더 많은 정보를 제공합니다. 타사 구성 요소가 누수되는지 여부를 알려줄 수도 있습니다.
발 그린 드 http://valgrind.org/
과
GDB http://www.gnu.org/software/gdb/
"Valgrind"를 실행하면 다음을 수행 할 수 있습니다.
1) 메모리 누수 식별 - 메모리 누수 수를 표시하고 누수 된 메모리가 할당 된 코드의 행을 가리 킵니다.
2) 메모리를 비 우려는 잘못된 시도를 지적하십시오 (예 : "삭제"의 부적절한 호출)
"Valgrind"사용 지침
1) -g 플래그를 사용하여 코드를 컴파일하십시오.
3) 쉘에서 다음을 실행하십시오.
valgrind --leak-check=yes myprog arg1 arg2
여기서 "myprog"는 컴파일 된 프로그램이고 "arg1", "arg2"는 프로그램의 인수입니다.
4) 결과는 malloc / new 호출에 대한 후속 호출이없는 무료 삭제 호출 목록입니다.
예를 들면 다음과 같습니다.
==4230== at 0x1B977DD0: malloc (vg_replace_malloc.c:136)
==4230== by 0x804990F: main (example.c:6)
malloc (해제되지 않은)이 어느 회선으로 호출되었는지 알려줍니다.
다른 사람들이 지적했듯이 모든 "신규"/ "malloc"호출마다 "삭제"/ "무료"호출이 있는지 확인하십시오.
gcc를 사용하면 gprof를 사용할 수 있습니다.
프로그래머가 메모리 누수를 찾는 방법을 알고 싶었습니다.
일부는 도구를 사용하고 일부는 피어 코드 검토를 통해 수행 할 수있는 작업을 수행합니다.
프로그램에서 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
나에게 : 동적으로 할당 된 객체를 만들 때마다 항상 해제 코드를 넣은 다음 사이에 코드를 채 웁니다. 코드 사이에 예외가없는 것이 확실하면 괜찮습니다. 그렇지 않으면 try-finally를 사용합니다 (C ++을 자주 사용하지 않습니다).
Visual Studio에는 C 런타임 라이브러리라는 메모리 누수 탐지기가 내장되어 있습니다. 기본 함수가 리턴 된 후 프로그램이 종료되면 CRT는 애플리케이션의 디버그 힙을 검사합니다. 여전히 디버그 힙에 할당 된 블록이 있으면 메모리 누수가있는 것입니다.
이 포럼 에서는 C / C ++에서 메모리 누수를 피하는 몇 가지 방법에 대해 설명합니다.
의 발생을 코드에서 검색 new
하고 소멸자에서 삭제가 일치하는 생성자 내에서 모두 발생하는지 확인하십시오. 이것이 해당 생성자에서 던질 수있는 유일한 작업인지 확인하십시오. 이 작업을 수행하는 간단한 방법은 모두 포인터 래핑하는 것입니다 std::auto_ptr
, 또는 boost::scoped_ptr
(당신이 의미를 이동할 필요가 있는지 여부에 따라). 향후 모든 코드의 경우 소멸자에서 리소스를 정리하는 객체가 모든 리소스를 소유하고 있는지 확인하십시오. 이동 의미론이 필요한 경우 r- 값 참조를 지원하는 컴파일러로 업그레이드하고 (VS2010은 믿습니다) 이동 생성자를 만들 수 있습니다. 그렇게하고 싶지 않다면 양심적 인 스왑 사용과 관련된 다양한 까다로운 기술을 사용하거나 Boost.Move 라이브러리를 사용해 볼 수 있습니다.
VLD (Visual Leak Detector) 는 Visual C ++를위한 강력하고 무료 인 오픈 소스 메모리 누수 탐지 시스템입니다.
Visual Studio 디버거에서 프로그램을 실행하면 Visual Leak Detector가 디버깅 세션이 끝날 때 메모리 누수 보고서를 출력합니다. 누수 보고서에는 누수 된 메모리 블록이 할당 된 방법을 보여주는 전체 호출 스택 이 포함됩니다. 호출 스택에서 라인을 두 번 클릭하여 편집기 창에서 해당 파일로 이동하십시오.
크래시 덤프 만있는 경우 Windbg !heap -l
명령을 사용하면 누수 된 힙 블록을 감지합니다. gflags 옵션 인“사용자 모드 스택 추적 데이터베이스 생성”을 열면 메모리 할당 호출 스택이 표시됩니다.
Windows에서는 CRT 디버그 힙을 사용할 수 있습니다 .
프로그램에 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
예, 수동 메모리 관리를 사용하지 마십시오 (전화 delete
또는 delete[]
수동으로 잘못 입력 한 경우). RAII 및 스마트 포인터를 사용하고 힙 할당을 절대 최소값으로 제한하십시오 (대부분 자동 변수로 충분합니다).
질문의 두 번째 부분에 대답하면
프로그램에 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
그렇습니다. 그리고 이것은 C와 C ++의 주요 차이점 중 하나입니다.
C ++에서는 사용자 코드를 호출 new
하거나 호출해서는 안됩니다 delete
. RAII 는 매우 일반적으로 사용되는 기술로 리소스 관리 문제를 거의 해결합니다. 프로그램의 모든 리소스 (리소스는 파일 핸들, 네트워크 소켓, 데이터베이스 연결 및 일반 메모리 할당, 경우에 따라 API 호출 쌍 (BeginX ( ) / EndX (), LockY (), UnlockY ())는 다음과 같은 클래스로 래핑되어야합니다.
- 생성자 가 리소스를 얻 습니다 (
new
리소스가 memroy 할당 인 경우 호출 하여) - 소멸자 는 리소스를 해제 하고
- 복사 및 할당이 방지되거나 (복사 생성자 및 할당 연산자를 개인용으로 만들거나) 기본 리소스를 복제하여 올바르게 작동하도록 구현되었습니다.
그런 다음이 클래스는 포인터를 호출 하여 저장 하지 않고 로컬, 스택 또는 클래스 멤버로 인스턴스화됩니다 new
.
종종 이러한 클래스를 직접 정의 할 필요는 없습니다. 표준 라이브러리 컨테이너도 이러한 방식으로 작동하므로 std::vector
벡터가 파괴 될 때에 저장된 객체 가 해제됩니다. 그래서 다시 (필요 컨테이너에 포인터를 저장하지 않습니다 당신이 전화 new
하고 delete
)이 아니라 객체 자체 (당신은 메모리 관리를 제공합니다 무료을 ). 마찬가지로 스마트 포인터 클래스를 사용하여 할당해야하는 객체를 쉽게 감쌀 수 있으며 new
수명을 제어 할 수 있습니다.
즉, 개체가 범위를 벗어나면 개체가 자동으로 삭제되고 리소스가 해제 및 정리됩니다.
코드 전체에서 일관되게이 작업을 수행하면 메모리 누수가 발생하지 않습니다. 누수 될 수 있는 모든 것은 소멸자와 연결되어 있으며, 컨트롤이 객체가 선언 된 범위를 벗어날 때 호출되도록 보장됩니다.
AddressSanitizer (ASan)는 빠른 메모리 오류 탐지기입니다. C / C ++ 프로그램에서 use-after-free 및 {heap, stack, global} 버퍼 오버 플로우 버그를 찾습니다. 다음을 찾습니다.
- 해제 후 사용 (매달린 포인터 역 참조)
- 힙 버퍼 오버 플로우
- 스택 버퍼 오버 플로우
- 글로벌 버퍼 오버 플로우
- 반품 후 사용
- 초기화 순서 버그
이 도구는 매우 빠릅니다. 계측 프로그램의 평균 속도 저하는 ~ 2x입니다.
MTuner 는 MSVC, GCC 및 Clang 컴파일러를 지원하는 무료 다중 플랫폼 메모리 프로파일 링, 누출 감지 및 분석 도구입니다. 특징은 다음과 같습니다.
- 타임 라인 기반 메모리 사용 내역 및 라이브 메모리 블록
- 힙, 메모리 태그, 시간 범위 등을 기반으로 한 강력한 메모리 작업 필터링
- 전체 소스 코드로 수동 계측을위한 SDK
- 명령 줄 사용을 통한 지속적인 통합 지원
- 호출 스택 트리 및 트리 맵 탐색
- 훨씬 더.
사용자는 GCC 또는 Clang 크로스 컴파일러를 사용하여 모든 소프트웨어 타겟팅 플랫폼을 프로파일 링 할 수 있습니다. MTuner는 Windows, PlayStation 4 및 PlayStation 3 플랫폼을 기본적으로 지원합니다.
Valgrind 도구를 사용하여 메모리 누수를 감지 할 수 있습니다.
또한 특정 함수에서 누수를 찾으려면 함수 끝에 exit (0)을 사용한 다음 Valgrind로 실행하십시오.
`$` valgrind ./your_CPP_program
사람에게 알려진 모든 도구의 비교
무엇보다도 먼저 아산 위키에서이 거대한 표를보십시오 : https://github.com/google/sanitizers/wiki/AddressSanitizerComparisonOfMemoryTools/d06210f759fec97066888e5f27c7e722832b0924
Google gperftools의 tcmalloc
https://github.com/gperftools/gperftools
Ubuntu 19.04에서의 사용법 :
sudo apt-get install google-perftools
gcc -ggdb3 -o main.out main.c -ltcmalloc
PPROF_PATH=/usr/bin/google-pprof \
HEAPCHECK=normal \
HEAPPROFILE=ble \
./main.out \
;
google-pprof main.out ble.0001.heap --text
간단한 테스트 프로그램 :
main.c
#include <stdlib.h>
void * my_malloc(size_t n) {
return malloc(n);
}
void leaky(size_t n, int do_leak) {
void *p = my_malloc(n);
if (!do_leak) {
free(p);
}
}
int main(void) {
leaky(0x10, 0);
leaky(0x10, 1);
leaky(0x100, 0);
leaky(0x100, 1);
leaky(0x1000, 0);
leaky(0x1000, 1);
}
프로그램 실행 결과에는 메모리 누수 분석이 포함됩니다.
WARNING: Perftools heap leak checker is active -- Performance may suffer
Starting tracking the heap
Dumping heap profile to ble.0001.heap (Exiting, 4 kB in use)
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 272 bytes in 2 objects
The 2 largest leaks:
Using local file ./main.out.
Leak of 256 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581d3 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581b5 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof ./main.out "/tmp/main.out.24744._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more re
Exiting with error code (instead of crashing) because of whole-program memory leaks
그리고 출력 google-pprof
에는 힙 사용량 분석이 포함됩니다.
Using local file main.out.
Using local file ble.0001.heap.
Total: 0.0 MB
0.0 100.0% 100.0% 0.0 100.0% my_malloc
0.0 0.0% 100.0% 0.0 100.0% __libc_start_main
0.0 0.0% 100.0% 0.0 100.0% _start
0.0 0.0% 100.0% 0.0 100.0% leaky
0.0 0.0% 100.0% 0.0 100.0% main
결과는 세 가지 누출 중 두 가지를 나타냅니다.
Leak of 256 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581d3 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581b5 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
왜 세 번째가 나타나지 않았는지 모르겠습니다
어쨌든 일반적으로 누수가 발생하면 많은 시간이 걸리고 실제 프로젝트에서 사용했을 때 누수 기능을 매우 쉽게 지적했습니다.
출력 자체에서 언급했듯이 이는 상당한 실행 속도 저하를 초래합니다.
Further documentation at:
- https://gperftools.github.io/gperftools/heap_checker.html
- https://gperftools.github.io/gperftools/heapprofile.html
See also: How To Use TCMalloc?
Tested in Ubuntu 19.04, google-perftools 2.5-2.
Address Sanitizer (ASan) also by Google
https://github.com/google/sanitizers
Previously mentioned at: How to find memory leak in a C++ code/project? TODO vs tcmalloc.
This is already integrated into GCC, so you can just do:
gcc -fsanitize=address -ggdb3 -o main.out main.c
./main.out
and execution outputs:
=================================================================
==27223==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4096 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f210 in main /home/ciro/test/main.c:20
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
Direct leak of 256 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f1f2 in main /home/ciro/test/main.c:18
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f1d4 in main /home/ciro/test/main.c:16
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
SUMMARY: AddressSanitizer: 4368 byte(s) leaked in 3 allocation(s).
which clearly identifies all leaks. Nice!
ASan can also do other cool checks such as out-of-bounds writes: Stack smashing detected
Tested in Ubuntu 19.04, GCC 8.3.0.
Valgrind
Previously mentioned at: https://stackoverflow.com/a/37661630/895245
Usage:
sudo apt-get install valgrind
gcc -ggdb3 -o main.out main.c
valgrind --leak-check=yes ./main.out
Output:
==32178== Memcheck, a memory error detector
==32178== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==32178== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==32178== Command: ./main.out
==32178==
==32178==
==32178== HEAP SUMMARY:
==32178== in use at exit: 4,368 bytes in 3 blocks
==32178== total heap usage: 6 allocs, 3 frees, 8,736 bytes allocated
==32178==
==32178== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091B4: main (main.c:16)
==32178==
==32178== 256 bytes in 1 blocks are definitely lost in loss record 2 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091D2: main (main.c:18)
==32178==
==32178== 4,096 bytes in 1 blocks are definitely lost in loss record 3 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091F0: main (main.c:20)
==32178==
==32178== LEAK SUMMARY:
==32178== definitely lost: 4,368 bytes in 3 blocks
==32178== indirectly lost: 0 bytes in 0 blocks
==32178== possibly lost: 0 bytes in 0 blocks
==32178== still reachable: 0 bytes in 0 blocks
==32178== suppressed: 0 bytes in 0 blocks
==32178==
==32178== For counts of detected and suppressed errors, rerun with: -v
==32178== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
So once again, all leaks were detected.
See also: How do I use valgrind to find memory leaks?
Tested in Ubuntu 19.04, valgrind 3.14.0.
In addition to the tools and methodes provided in the other anwers, static code analysis tools can be used to detect memory leaks (and other issues as well). A free an robust tool is Cppcheck. But there are a lot of other tools available. Wikipedia has a list of static code analysis tools.
Make certain that all the heap memory is successfully freed. There is no need if you never allocate memory on the heap. If you do, count the number of times you malloc memory, and count up the number of time you free memory.
Neither "new" or "delete" should ever be used in application code. Instead, create a new type that uses the manager/worker idiom, in which the manager class allocates and frees memory and forwards all other operations to the worker object.
Unfortunately this is more work than it should be because C++ doesn't have overloading of "operator .". It is even more work in the presence of polymorphism.
But this is worth the effort because you then don't ever have to worry about memory leaks, which means you don't even have to look for them.
참고URL : https://stackoverflow.com/questions/6261201/how-to-find-memory-leak-in-a-c-code-project
'Programming' 카테고리의 다른 글
C #에서 문자열을 DateTime으로 구문 분석 (0) | 2020.06.07 |
---|---|
CERT / PEM 인증서를 PFX 인증서로 변환 (0) | 2020.06.05 |
CSS를 사용하여 요소 앞에 줄 바꿈을 삽입하는 방법 (0) | 2020.06.05 |
모든 테이블 이름을 나열하는 PostgreSQL 쿼리? (0) | 2020.06.05 |
virtualenv 폴더 이름을 바꾸지 않고 이름 바꾸기 (0) | 2020.06.05 |