C ++ 코드 / 프로젝트에서 메모리 누수를 찾는 방법은 무엇입니까? 누수가 발견되지만 번거롭고

저는 Windows 플랫폼의 C ++ 프로그래머입니다. Visual Studio 2008을 사용하고 있습니다.

나는 보통 메모리 누수로 코드를 작성합니다.

일반적으로 코드를 검사하여 메모리 누수가 발견되지만 번거롭고 항상 좋은 접근 방식은 아닙니다.

유료 메모리 누수 감지 도구를 사용할 수 없기 때문에 메모리 누수를 피하는 가장 좋은 방법을 제안하기를 원했습니다.

  1. 프로그래머가 메모리 누수를 찾는 방법을 알고 싶습니다.
  2. 프로그램에 메모리 누수가 없는지 확인하기 위해 따라야하는 표준 또는 절차가 있습니까?


답변

명령

필요한 것

  • C ++ 능력
  • C ++ 컴파일러
  • 디버거 및 기타 조사 소프트웨어 도구

1

운영자 기본 사항을 이해하십시오. C ++ 연산자는 new힙 메모리를 할당합니다. delete조작자 해방 힙 메모리. 모든 newdelete대해 할당 한 동일한 메모리를 확보 할 수 있도록 다음을 사용해야합니다 .

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 ++ 컴파일러가 어떤 생성자 / 할당 연산자를 자동으로 생성하는지, 그리고 포인터를 소유 한 클래스가있는 경우의 의미 또는 소유하지 않은 객체에 대한 포인터가 포함 된 클래스가있는 경우의 의미에 대해 알아 봅니다 .

답변


답변

  1. Windows 용 디버깅 도구를 다운로드 하십시오 .
  2. gflags유틸리티를 사용하여 사용자 모드 스택 추적을 켜십시오.
  3. UMDH프로그램 메모리의 여러 스냅 샷을 만드는 데 사용 합니다. 메모리가 할당되기 전에 스냅 샷을 작성하고 프로그램에서 메모리가 누수되었다고 생각되는 지점에서 두 번째 스냅 샷을 작성하십시오. 프로그램에 일시 중지 또는 프롬프트를 추가 UMDH하여 스냅 샷 을 실행 하고 만들 수있는 기회를 제공 할 수 있습니다 .
  4. UMDH이번에는 두 스냅 샷을 서로 다른 모드로 다시 실행 하십시오. 그런 다음 메모리 누수가 의심되는 호출 스택이 포함 된 보고서를 생성합니다.
  5. gflags완료되면 이전 설정을 복원하십시오 .

UMDH전체 프로세스에서 메모리 할당을 감시하고 있기 때문에 CRT 디버그 힙보다 더 많은 정보를 제공합니다. 타사 구성 요소가 누수되는지 여부를 알려줄 수도 있습니다.


답변

“Valgrind”를 실행하면 다음을 수행 할 수 있습니다.

1) 메모리 누수 식별메모리 누수 수를 표시하고 누수 된 메모리가 할당 된 코드의 행을 가리 킵니다.

2) 메모리를 비 우려는 잘못된 시도 (예 : 부적절한 호출 delete) 를 지적하십시오.

“Valgrind”사용 지침

1) 여기에 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 ++을 자주 사용하지 않습니다).