it-swarm-ko.tech

C ++에서 메모리 누수를 피하기위한 일반 지침

C++ 프로그램에서 메모리가 누출되지 않도록하는 일반적인 팁은 무엇입니까? 동적으로 할당 된 메모리를 누가 확보해야하는지 어떻게 알 수 있습니까?

125
dulipishi

메모리를 수동으로 관리하는 대신 해당되는 경우 스마트 포인터를 사용하십시오.
Boost lib , TR1스마트 포인터 를 살펴보십시오.
스마트 포인터는 이제 C++ 11 이라는 C++ 표준의 일부입니다.

38
Andri Möll

RAII 및 스마트 포인터에 대한 모든 조언을 철저히 보증하지만 약간 더 높은 수준의 팁을 추가하고 싶습니다. 관리하기 가장 쉬운 메모리는 할당하지 않은 메모리입니다. 거의 모든 것이 참조 인 C # 및 Java와 같은 언어와 달리 C++에서는 가능할 때마다 객체를 스택에 배치해야합니다. Stroustrup 박사를 포함한 여러 사람들이 지적한 것처럼 C++에서 가비지 수집이 인기가 없었던 주된 이유는 잘 작성된 C++이 처음에는 많은 가비지를 생산하지 않기 때문입니다.

쓰지 마

Object* x = new Object;

또는

shared_ptr<Object> x(new Object);

그냥 쓸 수있을 때

Object x;
196
Ross Smith

사용 [~ # ~] raii [~ # ~]

  • 가비지 수집을 잊어 버리십시오 (대신 RAII를 사용하십시오). 가비지 콜렉터도 누출 될 수 있으며 (Java/C #에서 일부 참조를 "널링"하는 것을 잊어 버린 경우), 가비지 콜렉터는 자원을 처리하는 데 도움이되지 않습니다. Java에서 수동으로 수행하지 않거나 C #에서 "dispose"패턴을 사용하면 오브젝트가 범위를 벗어날 때 파일이 자동으로 해제되지 않습니다.
  • "함수 당 하나의 리턴"규칙 을 잊어 버리십시오. 이것은 누출을 피하는 좋은 C 조언이지만 예외 사용으로 인해 C++에서는 구식입니다 (대신 RAII 사용).
  • 그리고 "샌드위치 패턴"은 좋은 C 조언이지만 는 C++ 예외를 사용하기 때문에 (대신 RAII를 사용하십시오).

이 게시물은 반복적 인 것으로 보이지만 C++에서 알아야 할 가장 기본적인 패턴은 [~ # ~] raii [~ # ~] 입니다.

Boost, TR1 또는 심지어는 낮지 만 (충분히 효율적인) auto_ptr에서 스마트 포인터를 사용하는 법을 배우십시오 (그러나 그 한계를 알아야합니다).

RAII는 C++에서 예외 안전 및 리소스 처리의 기초이며, 다른 패턴 (샌드위치 등)이 둘 다를 제공하지 않습니다 (대부분의 경우 아무 것도 제공하지 않음).

RAII와 비 RAII 코드의 비교는 아래를 참조하십시오.

void doSandwich()
{
   T * p = new T() ;
   // do something with p
   delete p ; // leak if the p processing throws or return
}

void doRAIIDynamic()
{
   std::auto_ptr<T> p(new T()) ; // you can use other smart pointers, too
   // do something with p
   // WON'T EVER LEAK, even in case of exceptions, returns, breaks, etc.
}

void doRAIIStatic()
{
   T p ;
   // do something with p
   // WON'T EVER LEAK, even in case of exceptions, returns, breaks, etc.
}

[~ # ~] raii [~ # ~]

요약 (에서 주석 후 오우거 시편 33), RAII는 다음 세 가지 개념에 의존합니다.

  • 객체가 생성되면 작동합니다! 생성자에서 리소스를 얻습니다.
  • 객체 파괴로 충분합니다! 소멸자에서 무료 리소스를 사용하십시오.
  • 범위에 관한 모든 것입니다! 범위가 지정된 객체 (위의 doRAIIStatic 예제 참조)는 선언시 생성되며 종료 (반환, 중단, 예외 등)에 관계없이 실행이 범위를 종료하는 순간에 삭제됩니다.

이것은 올바른 C++ 코드에서 대부분의 객체가 new로 구성되지 않고 대신 스택에서 선언됨을 의미합니다. 그리고 new를 사용하여 생성 된 사람들은 모두 어쨌든 범위가 지정된 (예 : 스마트 포인터에 연결).

개발자는 수동 리소스 처리 (C에서 수행 한 것처럼 또는 Java의 try/finally이 경우) ...

편집 (2012-02-12)

"범위가 지정된 객체는 ... 종료 여부에 관계없이 파괴됩니다"는 전적으로 사실이 아닙니다. RAII를 속이는 방법이 있습니다. terminate ()의 풍미는 정리를 우회합니다. 이와 관련하여 exit (EXIT_SUCCESS)는 옥시 모론입니다.

빌헬름 텔

wilhelmtell 는 그것에 대해 꽤 옳습니다. RAII를 속이는 방법은 exceptional 있습니다.

C++ 코드가 종료, 종료 등으로 어지럽히 지 않기 때문에 exceptional 방식이거나 예외가있는 경우 처리되지 않은 예외 는 프로세스를 중단시키고 청소 후가 아니라 메모리 이미지를 그대로 덤프합니다.

그러나 거의 발생하지 않지만 여전히 발생할 수 있기 때문에 이러한 경우에 대해 알아야합니다.

(캐주얼 C++ 코드에서 terminate 또는 exit를 호출하는 사람은 누구입니까? ... [~ # ~] glut [~ # ~] :이 라이브러리는 매우 C 지향적이며 C++ 개발자가 스택 할당 데이터 를 신경 쓰지 않는 것과 같은 일을 어렵게 만들기 위해 적극적으로 설계합니다. 또는 주 루프 에서 돌아 오지 않는 것에 대한 "흥미로운"결정이있는 경우 ... 나는 그것에 대해 언급하지 않습니다).

101
paercebal

boost 's smart pointers 와 같은 스마트 포인터를보고 싶을 것입니다.

대신에

int main()
{ 
    Object* obj = new Object();
    //...
    delete obj;
}

boost :: shared_ptr은 참조 횟수가 0이되면 자동으로 삭제됩니다.

int main()
{
    boost::shared_ptr<Object> obj(new Object());
    //...
    // destructor destroys when reference count is zero
}

마지막 참고 사항 인 "참조 횟수가 0 일 때 가장 멋진 부분입니다. 따라서 개체를 여러 명 사용하는 경우 개체가 아직 사용 중인지 여부를 추적 할 필요가 없습니다. 공유 포인터, 그것은 파괴된다.

그러나 이것은 만병 통치약이 아닙니다. 기본 포인터에 액세스 할 수 있지만 수행중인 작업에 대한 확신이 없으면 타사 API에 전달하지 않습니다. 많은 경우, 작성 범위가 완료된 후 작업을 수행하기 위해 다른 스레드에 "게시"하는 것들. 이것은 Win32의 PostThreadMessage에서 일반적입니다.

void foo()
{
   boost::shared_ptr<Object> obj(new Object()); 

   // Simplified here
   PostThreadMessage(...., (LPARAM)ob.get());
   // Destructor destroys! pointer sent to PostThreadMessage is invalid! Zohnoes!
}

항상 그렇듯이 모든 도구와 함께 사고 뚜껑을 사용하십시오 ...

25
Doug T.

RAII 을 읽고 이해했는지 확인하십시오.

12
Hank

대부분의 메모리 누수는 개체 소유권과 수명에 대해 명확하지 않은 결과입니다.

가장 먼저 할 일은 가능하면 스택에 할당하는 것입니다. 이것은 어떤 목적으로 단일 객체를 할당해야하는 대부분의 경우를 다룹니다.

객체를 '새로 작성'해야하는 경우 대부분의 수명 동안 나머지 한 명의 명백한 소유자가 있습니다. 이 상황에서는 포인터로 저장된 개체를 '소유'하도록 설계된 컬렉션 모음을 사용하는 경향이 있습니다. 그것들은 STL 벡터 및 맵 컨테이너로 구현되지만 몇 가지 차이점이 있습니다.

  • 이 모음은 복사하거나 할당 할 수 없습니다. (한 번 객체를 포함합니다.)
  • 객체에 대한 포인터가 삽입됩니다.
  • 콜렉션이 삭제되면 소멸자가 콜렉션의 모든 오브젝트에서 먼저 호출됩니다. (파괴되고 비워지지 않으면 주장하는 다른 버전이 있습니다.)
  • 포인터를 저장하기 때문에 상속 된 객체를 이러한 컨테이너에 저장할 수도 있습니다.

STL에 대한 나의 비판은 그것이 Value 객체에 너무 집중되어 있고 대부분의 응용 프로그램에서 객체는 컨테이너에 사용하기 위해 의미있는 사본 의미가없는 독특한 엔티티입니다.

11
Jeroen Dirks

바, 당신은 어린 아이들과 새로운 쓰레기 수집가들 ...

"소유권"에 대한 매우 강력한 규칙-소프트웨어를 통해 개체를 삭제할 권한이있는 개체 또는 부분 포인터가 "소유"하거나 "단지 보거나 만지지 마십시오"라는 명확한 설명과 현명한 변수 이름 누가 무엇을 소유하는지 결정하려면 모든 서브 루틴 또는 방법 내에서 가능한 한 "샌드위치"패턴을 따르십시오.

create a thing
use that thing
destroy that thing

때로는 광범위하게 다른 장소에서 창조하고 파괴해야 할 때가 있습니다. 나는 그것을 피하기 어렵다고 생각합니다.

복잡한 데이터 구조를 필요로하는 모든 프로그램에서 "소유자"포인터를 사용하여 다른 객체를 포함하는 객체의 엄격한 명확한 트리를 만듭니다. 이 트리는 응용 프로그램 도메인 개념의 기본 계층을 모델링합니다. 예를 들어 3D 장면은 객체, 조명, 텍스처를 소유합니다. 프로그램이 종료 될 때 렌더링이 끝나면 모든 것을 파괴 할 수있는 명확한 방법이 있습니다.

하나의 엔티티가 다른 엔티티에 액세스해야 할 때마다, 또는 다른 것들을 스캔하기 위해 필요할 때마다 다른 많은 포인터가 정의됩니다. 이것들은 "그냥보고있는"것입니다. 3D 장면 예제의 경우, 오브젝트는 텍스처를 사용하지만 소유하지는 않습니다. 다른 물체도 같은 질감을 사용할 수 있습니다. 오브젝트를 파괴하면 not는 텍스처를 파괴합니다.

예, 시간이 많이 걸리지 만 그게 내가하는 일입니다. 메모리 누수 나 다른 문제는 거의 없습니다. 그러나 저는 고성능 과학, 데이터 수집 및 그래픽 소프트웨어의 제한된 영역에서 일합니다. 나는 종종 은행 및 전자 상거래, 이벤트 중심 GUI 또는 높은 네트워크 비동기 혼란과 같은 거래를 다루지 않습니다. 아마도 새로운 방식으로 유리한 점이있을 것입니다!

10
DarenW

좋은 질문입니다!

c ++를 사용 중이고 게임과 같은 실시간 CPU 및 메모리 보드 응용 프로그램을 개발하는 경우 자체 메모리 관리자를 작성해야합니다.

나는 당신이 더 잘 할 수 있다고 생각합니다. 다양한 작가들의 흥미로운 작품들을 합치면 힌트를 줄 수 있습니다.

  • 고정 크기 할당자는 인터넷 어디에서나 심하게 논의됩니다.

  • Small Object Allocation은 2001 년 Alexandrescu에 의해 그의 완벽한 저서 "Modern c ++ design"에서 소개되었습니다.

  • Dimitar Lazarov가 작성한 "고성능 힙 할당 자"라는 Game Programming Gem 7 (2008)의 놀라운 기사에서 (소스 코드가 배포 된) 큰 발전을 볼 수 있습니다.

  • 훌륭한 리소스 목록은 this article에 있습니다.

멍청한 쓸모없는 할당자를 직접 작성하지 마십시오 ... 먼저 자신을 문서화하십시오.

8
ugasoft

C++에서 메모리 관리에 널리 사용되는 기술 중 하나는 RAII 입니다. 기본적으로 생성자/소멸자를 사용하여 리소스 할당을 처리합니다. 물론 예외 안전으로 인해 C++에는 다른 눈에 띄지 않는 세부 사항이 있지만 기본 아이디어는 매우 간단합니다.

이 문제는 일반적으로 소유권 중 하나에 해당합니다. Scott Meyers의 Effective C++ 시리즈와 Andrei Alexandrescu의 Modern C++ Design을 읽는 것이 좋습니다.

5
Jason Dagit

누출되지 않는 방법에 대해서는 이미 많이 있지만 누출을 추적 할 수있는 도구가 필요한 경우 다음을 살펴보십시오.

5
fabiopedrosa

당신이 할 수있는 모든 곳에서 사용자 스마트 포인터! 모든 종류의 메모리 누수가 사라집니다.

4
DougN

프로젝트 전체에서 메모리 소유권 규칙을 공유하고 알 수 있습니다. COM 규칙을 사용하면 최상의 일관성을 유지할 수 있습니다 ([in] 매개 변수는 호출자가 소유하고, 수신자는 복사해야합니다. [out] 매개 변수는 호출자가 소유하고, 수신자는 참조를 유지하는 경우 복사해야합니다.)

4
Seth Morris

valgrind는 런타임시 프로그램 메모리 누수를 확인하는 좋은 도구입니다.

대부분의 Linux (Android 포함) 및 Darwin에서 사용할 수 있습니다.

프로그램에 대한 단위 테스트를 작성하는 데 사용하는 경우 테스트에서 체계적으로 실행하는 습관을 가져야합니다. 초기 단계에서 많은 메모리 누수를 방지 할 수 있습니다. 일반적으로 전체 소프트웨어에서 수행하는 간단한 테스트에서이를 쉽게 찾아 낼 수 있습니다.

물론이 조언은 다른 메모리 검사 도구에도 유효합니다.

4
Joseph

또한 std 라이브러리 클래스 (예 : 벡터)가있는 경우 수동으로 할당 된 메모리를 사용하지 마십시오. 가상 소멸자가 있다는 규칙을 위반했는지 확인하십시오.

3
Joseph

무언가에 대해 스마트 포인터를 사용할 수 없거나 사용할 수없는 경우 (거대한 붉은 깃발이어야하지만) 다음을 사용하여 코드를 입력하십시오.

allocate
if allocation succeeded:
{ //scope)
     deallocate()
}

명백하지만 입력해야합니다. before 범위에 코드를 입력하십시오.

2
Seth Morris

중요도에 따른 팁 :

-Tip # 1 항상 소멸자를 "가상"으로 선언해야합니다.

-팁 # 2 RAII 사용

-Tip # 3 부스트의 스마트 포인터 사용

-팁 # 4 버그가있는 Smartpointer를 작성하지 말고 boost를 사용하십시오 (현재 프로젝트에서 boost를 사용할 수 없으며 자체 스마트 포인터를 디버깅해야하는데 어려움을 겪었습니다. 같은 경로를 다시 사용하지만 지금은 다시 의존성을 높일 수 없습니다.)

팁 # 5 캐주얼/비 성능이 중요하다면 (수천 개의 오브젝트가있는 게임 에서처럼) Thorsten Ottosen의 부스트 포인터 컨테이너를 살펴보십시오

-Tip # 6 Visual Leak Detection의 "vld"헤더와 같이 선택한 플랫폼에 대한 누출 감지 헤더를 찾으십시오.

2
Robert Gould

이러한 버그의 빈번한 원인은 개체에 대한 참조 나 포인터를 허용하지만 소유권을 명확하게하지 않는 방법이있는 경우입니다. 스타일과 주석 규칙은이를 덜 가능하게합니다.

함수가 객체의 소유권을 갖는 경우가 특별한 경우가되게하십시오. 이런 상황이 발생하면이를 나타내는 헤더 파일의 함수 옆에 주석을 작성하십시오. 대부분의 경우 객체를 할당하는 모듈 또는 클래스가 객체 할당을 취소해야합니다.

Const를 사용하면 어떤 경우에는 많은 도움이 될 수 있습니다. 함수가 오브젝트를 수정하지 않고 리턴 후에도 지속되는 참조를 저장하지 않으면 const 참조를 승인하십시오. 호출자의 코드를 읽음으로써 함수가 객체의 소유권을 수락하지 않았 음을 알 수 있습니다. 동일한 함수가 const가 아닌 포인터를 수락하도록 할 수 있었으며 호출자는 수신자가 소유권을 수락했다고 가정했을 수도, 아닐 수도 있지만 const 참조로는 의문의 여지가 없습니다.

인수 목록에 상수가 아닌 참조를 사용하지 마십시오. 호출자 코드를 읽을 때 수신자가 매개 변수에 대한 참조를 유지했을 가능성이 매우 불분명합니다.

참조 카운트 포인터를 권장하는 의견에 동의하지 않습니다. 이것은 일반적으로 잘 작동하지만 버그가 있고 작동하지 않을 때, 특히 소멸자가 멀티 스레드 프로그램과 같이 사소한 것을 수행하는 경우에는 작동하지 않습니다. 너무 세지 않은 경우 참조 카운트가 필요하지 않도록 디자인을 확실히 조정하십시오.

2
Jonathan

가능하면 boost shared_ptr 및 표준 C++ auto_ptr을 사용하십시오. 그것들은 소유권 의미를 전달합니다.

Auto_ptr을 반환하면 호출자에게 메모리 소유권을 부여하고 있음을 알리는 것입니다.

Shared_ptr을 반환하면 호출자에게 참조가 있고 소유권에 참여한다고 알리는 것은 전적으로 자신의 책임이 아닙니다.

이러한 의미는 매개 변수에도 적용됩니다. 호출자가 auto_ptr을 전달하면 소유권을 부여하는 것입니다.

1
Justin Rudd
  • 객체를 동적으로 할당하지 마십시오. 클래스에 적절한 생성자와 소멸자가있는 한, 클래스 유형의 변수를 가리키는 포인터가 아닌 변수를 사용하면 컴파일러가 자동으로 할당하기 때문에 동적 할당 및 할당 해제를 피할 수 있습니다.
    실제로 이것은 "스마트 포인터"에 의해 사용되는 메커니즘이며 다른 몇몇 작가는 RAII라고도합니다. ;-).
  • 객체를 다른 함수에 전달할 때는 포인터보다 참조 매개 변수를 선호하십시오. 이것은 몇 가지 가능한 오류를 피합니다.
  • 가능한 경우 매개 변수 const, 특히 객체에 대한 포인터를 선언하십시오. 그렇게하면 객체를 "우연히"해제 할 수 없습니다 (const를 ;-) 버리지 않는 한).
  • 메모리 할당 및 할당 해제를 수행하는 프로그램의 위치 수를 최소화하십시오. 예 : 동일한 유형을 여러 번 할당하거나 해제하는 경우 해당 함수 (또는 팩토리 메소드 ;-)를 작성하십시오.
    이 방법으로 필요한 경우 디버그 출력 (주소가 할당 및 할당 해제되는 등)을 쉽게 만들 수 있습니다.
  • 팩토리 함수를 사용하여 단일 함수에서 여러 관련 클래스의 오브젝트를 할당하십시오.
  • 클래스에 가상 소멸자가있는 공통 기본 클래스가있는 경우 동일한 함수 (또는 정적 메서드)를 사용하여 모든 클래스를 해제 할 수 있습니다.
  • Purify (불행히도 $/€/...)와 같은 도구로 프로그램을 확인하십시오.
1
mh.

메모리를 수동으로 관리하려는 경우 두 가지 경우가 있습니다.

  1. 객체를 만들거나 (아마도 간접적으로 새 객체를 할당하는 함수를 호출하여) 객체를 사용하거나 호출하는 함수에서 사용합니다.
  2. 누군가 나에게 참조를 줬으므로 나는 그것을 풀어서는 안된다.

이러한 규칙 중 하나라도 위반해야하는 경우 문서화하십시오.

포인터 소유권에 관한 것입니다.

1
Null303

valgrind (* nix 플랫폼에서만 사용 가능)는 매우 멋진 메모리 검사기입니다.

1
Ronny Brendel

다른 사람들은 스마트 포인터와 같이 처음에 메모리 누수를 피하는 방법을 언급했습니다. 그러나 프로파일 링 및 메모리 분석 도구는 종종 메모리 문제가 발생하면이를 추적 할 수있는 유일한 방법입니다.

Valgrind memcheck 는 훌륭한 무료입니다.

1
eli

MSVC의 경우에만 각 .cpp 파일의 맨 위에 다음을 추가하십시오.

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

그런 다음 VS2003 이상으로 디버깅 할 때 프로그램이 종료 될 때 누수에 대해 알려줍니다 (새/삭제 추적). 기본이지만 과거에 도움이되었습니다.

1
Rob

C++는 RAII를 염두에두고 설계되었습니다. C++에서 메모리를 관리하는 더 좋은 방법은 없다고 생각합니다. 그러나 로컬 범위에 매우 큰 청크 (버퍼 객체와 같은)를 할당하지 않도록주의하십시오. 스택 오버플로가 발생할 수 있으며 해당 청크를 사용하는 동안 범위 검사에 결함이 있으면 다른 변수를 덮어 쓰거나 주소를 반환하여 모든 종류의 보안 허점을 초래할 수 있습니다.

0
artificialidiot

다른 장소에서 할당하고 파괴하는 유일한 예 중 하나는 스레드 생성 (전달하는 매개 변수)입니다. 그러나이 경우에도 쉽습니다. 스레드를 생성하는 함수/방법은 다음과 같습니다.

struct myparams {
int x;
std::vector<double> z;
}

std::auto_ptr<myparams> param(new myparams(x, ...));
// Release the ownership in case thread creation is successfull
if (0 == pthread_create(&th, NULL, th_func, param.get()) param.release();
...

대신 스레드 함수

extern "C" void* th_func(void* p) {
   try {
       std::auto_ptr<myparams> param((myparams*)p);
       ...
   } catch(...) {
   }
   return 0;
}

꽤 쉬운가요? 스레드 생성에 실패하면 auto_ptr에 의해 리소스가 해제 (삭제)됩니다. 그렇지 않으면 소유권이 스레드로 전달됩니다. 스레드가 너무 빠르면 생성 후 리소스를 해제하기 전에 어떻게해야합니까?

param.release();

주요 기능/메소드에서 호출됩니까? 아무것도! 우리는 auto_ptr을 '알려'할당 해제를 무시하기 때문입니다. C++ 메모리 관리가 쉽지 않습니까? 건배,

에마!

0
Emanuele Oriani

다른 리소스 (핸들, 파일, DB 연결, 소켓 등)를 관리하는 것과 같은 방식으로 메모리를 관리합니다. GC는 그들에게 도움이되지 않습니다.

0
Nemanja Trifunovic

메모리 할당 기능을 가로 챌 수 있으며 프로그램 종료시 해제되지 않은 일부 메모리 영역이 있는지 확인할 수 있습니다 (응용 프로그램에 all 에는 적합하지 않음).

또한 연산자 new 및 delete 및 기타 메모리 할당 기능을 대체하여 컴파일 타임에 수행 할 수도 있습니다.

예를 들어 다음을 확인하십시오. site [C++에서 메모리 할당 디버깅] 참고 : delete 연산자에는 다음과 같은 트릭이 있습니다.

#define DEBUG_DELETE PrepareDelete(__LINE__,__FILE__); delete
#define delete DEBUG_DELETE

일부 변수에 파일 이름을 저장할 수 있으며 과부하 된 삭제 연산자는 파일이 호출 된 위치를 알 수 있습니다. 이렇게하면 프로그램에서 모든 삭제 및 malloc을 추적 할 수 있습니다. 메모리 검사 순서가 끝나면 할당 된 메모리 블록이 파일 이름과 행 번호로 식별하여 '삭제되지 않은'메모리 블록을보고 할 수 있어야합니다.

Visual Studio에서 BoundsChecker 과 같은 것을 시도해 볼 수도 있습니다. 이는 매우 흥미롭고 사용하기 쉽습니다.

0
INS

우리는 모든 할당 함수를 앞에 짧은 문자열을 추가하고 끝에 센티넬 플래그를 추가하는 레이어로 래핑합니다. 예를 들어 "myalloc (pszSomeString, iSize, iAlignment); 또는 new ("description ", iSize) MyObject ();를 호출하면 지정된 크기와 헤더 및 센티넬에 충분한 공간을 내부적으로 할당 할 수 있습니다. 디버그가 아닌 빌드에 대해서는 이것을 언급하는 것을 잊지 마십시오!이 작업을 수행하는 데 약간의 메모리가 더 필요하지만 이점은 비용보다 훨씬 큽니다.

여기에는 세 가지 이점이 있습니다. 먼저 특정 '영역'에 할당 된 코드에 대한 빠른 검색을 수행하여 해당 코드가 누수 될 때 정리하지 않아도 코드 누출을 쉽고 빠르게 추적 할 수 있습니다. 또한 모든 센티넬이 손상되지 않았는지 확인하여 경계를 덮어 쓴 시점을 감지하는 것이 유용 할 수 있습니다. 이로 인해 숨겨져있는 충돌이나 배열 실수를 찾으려고 할 때 많은 시간이 절약되었습니다. 세 번째 이점은 메모리 사용을 추적하여 큰 플레이어가 누구인지 확인하는 것입니다. 예를 들어, '소리'가 예상보다 더 많은 공간을 차지할 때 MemDump의 특정 설명을 조합하여 알려줍니다.

0
screenglow