저는 Windows 플랫폼의 C ++ 프로그래머입니다. Visual Studio 2008을 사용하고 있습니다.
나는 보통 메모리 누수로 코드를 작성합니다.
일반적으로 코드를 검사하여 메모리 누수가 발견되지만 번거롭고 항상 좋은 접근 방식은 아닙니다.
유료 메모리 누수 감지 도구를 사용할 수 없기 때문에 메모리 누수를 피하는 가장 좋은 방법을 제안하기를 원했습니다.
- 프로그래머가 메모리 누수를 찾는 방법을 알고 싶습니다.
- 프로그램에 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
답변
명령
필요한 것
- C ++ 능력
- C ++ 컴파일러
- 디버거 및 기타 조사 소프트웨어 도구
1
운영자 기본 사항을 이해하십시오. C ++ 연산자는 new
힙 메모리를 할당합니다. delete
조작자 해방 힙 메모리. 모든 new
에 delete
대해 할당 한 동일한 메모리를 확보 할 수 있도록 다음을 사용해야합니다 .
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
하나의 객체를 무료로 자체. 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 디버그 힙보다 더 많은 정보를 제공합니다. 타사 구성 요소가 누수되는지 여부를 알려줄 수도 있습니다.
답변
“Valgrind”를 실행하면 다음을 수행 할 수 있습니다.
1) 메모리 누수 식별 – 메모리 누수 수를 표시하고 누수 된 메모리가 할당 된 코드의 행을 가리 킵니다.
2) 메모리를 비 우려는 잘못된 시도 (예 : 부적절한 호출 delete
) 를 지적하십시오.
“Valgrind”사용 지침
2) -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
(해제되지 않은) 어느 라인에서 호출 되었는지 알려줍니다 .
다른 사람들이 지적했듯이 모든 new
/ malloc
호출 마다 후속 delete
/ free
호출 이 있는지 확인하십시오 .
답변
gcc를 사용하면 gprof를 사용할 수 있습니다.
프로그래머가 메모리 누수를 찾는 방법을 알고 싶었습니다.
일부는 도구를 사용하고 일부는 피어 코드 검토를 통해 수행 할 수있는 작업을 수행합니다.
프로그램에서 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?
나를 위해 : 동적으로 할당 된 객체를 만들 때마다 항상 해제 코드를 넣은 다음 코드를 채 웁니다. 코드 사이에 예외가없는 것이 확실하면 괜찮습니다. 그렇지 않으면 try-finally를 사용합니다 (C ++을 자주 사용하지 않습니다).