2016-07-05 5 views
0

빈 콘솔 응용 프로그램을 생성하고 STL 컨테이너를 사용하면 응용 프로그램이 닫힐 때 FastMM이 메모리 누수를보고합니다. 예를 들어C++ Builder 6의 STL 컨테이너에서 FastMM이 메모리 누수를보고합니다.

, 나는 std::vector<int>main()에서 작성하는 경우 :

std::vector<int> v; 

컴파일, 실행 및 닫기, 누출이보고되지 않습니다.

내가 할 경우

std::vector<int> v; 
v.push_back(100); 

내가 얻을 :

이 응용 프로그램은 메모리를 유출했다. 소 블록 누출은 :

309-340 바이트 : 알 X 1

마찬가지로, I는보고 누출 얻을 :

std::vector<int> v; 
v.push_back(100); 
v.clear(); 

또한 누설이보고되어

std::vector<int> v; 
v.reserve(1); 

std::deque과 같은 일부 컨테이너의 경우 내용을 변경하지 않고도 누수를 표시 할 수 있습니다. 응용 프로그램이 종료되면 orted.

아무도 무슨 일이 일어나고 있는지 설명 할 수 있습니까? 저는 Borland C++ Builder 6와 FastMM4를 사용합니다. 나는 FastMMOptions.inc에서 다양한 설정을 변경했지만 아직 이러한 누수가보고됩니다.

+3

[볼랜드 C++ 빌더 6] (https://en.wikipedia.org/wiki/C%2B%2BBuilder#Version_history)은 2002 년에 나온 것으로 보인다. 현대 컴파일러? 심지어 최신 버전의 C++ Builder? 14 년은 소프트웨어면에서 오랜 시간입니다. – CoryKramer

+0

내가 말하기를, 코드 스 니펫을 감안할 때, 컴파일러에 의한 잘못된'std :: vector' 구현 이외의 (주변 컨텍스트를 보지 않고) 메모리 누출을 일으킬만한 것이 없다는 것입니다. 또는 누출 감지기에 의해보고 된 오 탐지. – CoryKramer

+0

예, 우리는 새로운 환경에서 볼랜드 XE7과 새로운 프로젝트를 개발했습니다. 그러나 기존 프로젝트에서 메모리 누수를 조사해야합니다. 기존 프로젝트에서는 크기 때문에 XE7로 마이그레이션하지 않았습니다. FastMM은 매우 유용하지만, STL이 코드의 여러 곳에서 사용되고 있기 때문에, 혼란스러운 부분을 지적하고 있습니다. – bboydushko

답변

1

vector의 내부 배열에 사용되는 메모리의 할당을 해제하지 않는 std::vector 지우기 이것은 단지 어레이 내부 항목 자폭 다음 세트가 새로운 재사용 될 수 있도록 배열 자체가 아직 할당 std::vector::size() 0으로 vector에 푸시 된 항목 vector의 소멸자는 배열을 할당 해제합니다.

C++ 빌더 6에서 기본 STL 라이브러리는 STLPort (C++ 빌더 2006에서는 Dinkumware로 대체 됨)입니다. ~std::vector()의 STLPort 구현은 (clear()이 호출 된 것처럼) 배열 항목을 파괴하지만 배열 자체를 할당 해제하지 않으므로 사용자가보고있는 "누출"입니다. 이는 실제로 누출에 전부 된 STLport 웹 사이트에 다음과 같은 질문에 따라 대부분의 경우에

Q6.2 My tool detect memory leaks in application with STLport. Is this leak from STLport?

A6.2이 몇 가지 도구가 잘못 지원하는 '의사 메모리 누수'이다.

STLport의 기본 컴파일에서 노드 할당자는 내부 메모리를 할당하는 데 사용됩니다. 노드 할당자는 큰 메모리 덩어리를 미리 할당하고 작은 메모리 블록을 나눠서 작동합니다. 메모리 청크는 STLport을 사용하는 응용 프로그램을 실행하는 동안 해제되지 않습니다. 즉, 시스템에 반환되지 않습니다. BoundsChecker, Purify 또는 Valgrind와 같은 도구 (memorytml 누수를 확인하는 도구, 더 이상 사용하지 않을 때 해제되지 않는 메모리)가 있습니다. 이 도구는 STLport의 노드 할당자를 사용할 때 잘못된 메모리 누수를보고 할 수 있습니다.일반적으로 메모리 청크는 응용 프로그램 끝에서 해제되지만 메모리 검사기는 일반적으로 해당 지점 전에 메모리 누수를보고합니다. 내부적으로 STLport를 사용하고 정적으로 링크되는 공유 라이브러리 (예 : DLL,이 문제는 Windows DLL 모델에만 해당)를 사용할 때 또 다른 메모리 문제가보고 될 수 있습니다. 메모리가 dll에 할당되고 다른 메모리로 릴리스되면 STLport 노드 할당자는 향후 사용을 위해 릴리스 된 메모리를 유지합니다. 이 메모리를 사용하지 않으면 실제 메모리 누출이없는 경우에도 appli가 중단 될 때까지 응용 프로그램의 전역 메모리 사용량이 증가합니다. 이것이 왜 dll에서 모든 것을 일관성있게 구성해야하는지, 정적 lib에서 모든 것을 일관되게 사용해야하는 이유입니다.

의사 메모리 누수를 제거하는 방법이 있습니다 (메모리가 프로그램 끝에 올바르게 해제되어 있기 때문에 누출은 단지 의사입니다). STLport에서 사용되는 다른 할당자를 사용할 수 있습니다. 파일을 열고 "stlport/stl/_site_config.h" 및 주석 중 하나를 다음 중 하나를

_STLP_USE_NEWALLOC enables a simple allocator that uses "new/delete" 
_STLP_USE_MALLOC  enables a simple allocator that uses "malloc/free" 

새로운/할당은 메모리 기아을 추적 컴파일러 문서 또는 자세한 내용은 C++ 표준에 set_new_handler 볼 진입 점을 제공하는 장점이 있습니다 삭제 .

또는 다음 기호를 정의하여 "stlport/stl/_site_config.h"에서 주석 처리를 제거하면됩니다.

_STLP_LEAKS_PEDANTIC 

기호는 모든 메모리 청크를 강제로 해제합니다. 또한 설정 파일에있는 심볼 주변의 주석을 참조하십시오.

파일을 변경하면 STLport와 응용 프로그램 및 모든 종속 라이브러리를 다시 컴파일해야합니다.

또한 STLport의 메모리 문제를 디버깅하는 데 도움이되는 몇 가지 정의가 있습니다.

_STLP_DEBUG_ALLOC 
_STLP_DEBUG_UNINITIALIZED   

당신은 이러한 옵션 된 STLport를 재 구축 할 필요가 없습니다,하지만 당신은 : _STLP_DEBUG 모드에서는 단지도 하나 "./stlport/stl_user_config.h"또는 프로젝트 설정에서 다음 기호를 정의 파일을 변경하면 응용 프로그램과 모든 종속 라이브러리를 다시 빌드 할 수 있습니다.

이전 C++ 빌더 버전에서 사용 된 RogueWave STL은 이전 버전과의 하위 호환성을 위해 C++ 빌더 6과 함께 제공되며이 문제가 발생하지 않습니다. 프로젝트의 조건부 목록에 _USE_OLD_RW_STL을 정의하여 STLPort에서 RogueWave로 전환 할 수 있습니다.

+0

우수하고 유익한 답변입니다. '_USE_OLD_RW_STL'을 정의하면 FastMM은 프로젝트에서 사용 된 컨테이너 ('std :: vector'' std :: list'' std :: deque')의 누수를보고하지 않습니다. 고맙습니다. 지금 메모리 누수 보고서를 검토하는 것이 훨씬 쉽습니다. – bboydushko

+0

내가 알아 차린 또 하나의 사실은'std :: cout'의 어떤 사용이라도 누출을보고합니다. 다행히도 우리 코드에는 그다지 많지는 않지만, 다른 훌륭한 '마술 조건부 정의'를 알고 있으면 보고서에 나타나는 이들을 막을 수 있습니다. 예 :'std :: cout << "hello"<< endl;'보고서 : 13 - 20 바이트 : 알 수 없음 x 1 21 - 36 바이트 : std :: codecvt x 1 알 수 없음 × 2 37-52 바이트 : 알 × 2 53-68 바이트 : 표준 : CTYPE X 1, X locale_imp __rwstd :: 2 85-100 바이트 : 알 × 2 485-532 바이트 : X 알 3 ,'printf ("hello \ n");는 누수가 없다고보고합니다. – bboydushko