안부 게시판에 Gerndal님이 아래의 코드를 실행하면 메모리 leak이 난다고 알려 주셨습니다.

 

#include "stdafx.h"

#include <ppl.h>

using namespace Concurrency;

 

int main()

{

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 

parallel_invoke( [] { }, [] { } );

return 0;

}

 

코드를 보면 메모리 leak이 날 조건이 하나도 없습니다. 그런데 왜 메모리 leak이 날까요?

영문판 MSDN 커뮤니티에 가보면 같은 문제로 질문하고 있는 것을 찾을 수 있습니다.

 

메모리 leak이 감지되는 것은 정말 메모리 leak이 발생한 것은 아닙니다. 문제는 ConcRT의 스케줄러가 해제되기 전에 프로그램이 먼저 종료되기 때문에 발생하는 것입니다.

 

위 코드를 보면 스케줄러와 관련된 코드는 하나도 보이지 않지만 암묵적으로 사용하고 있습니다.

이 문제를 해결하기 위해서는 스케줄러를 시작 부분에서 명시적으로 정의하고 프로그램이 종료하기 전에 스케줄러를 명시적으로 해제하는 것으로 해결할 수 있습니다( 혹은 정말 메모리 leak이 아니니 그냥 무시해도 됩니다 ).

 

 

메모리 leak 경고를 발생시키지 않기 위해서는 아래와 같이 하면 됩니다.

 

int main()

{

    HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

    CurrentScheduler::Create( SchedulerPolicy() );

    CurrentScheduler::RegisterShutdownEvent( hEvent );

 

 

    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

 

    parallel_invoke( [] {}, [] {} );

 

 

    CurrentScheduler::Detach();

    WaitForSingleObject( hEvent, INFINITE );

    CloseHandle( hEvent );

    Sleep(500);

 

    return 0;

}

 

암묵적으로 스케줄러를 정의했다면 프로그램이 종료될 때 깔끔하게 해제되어야 하는데 이 부분이 매끄럽지 못한 것이 아쉽습니다. 현재 관련 개발자는 이번 버전에서는 깔끔하게 처리하는 부분을 미처 넣지 못했지만 꼭 다음 버전(VC++ 11)에서는 꼭 해결하겠다고 이야기 합니다.

 

 

ps : 이것은 415일 세션에서 제가 언급하였습니다만 블로그에는 포스팅을 늦게 하게 되었습니다.