Home > C, C++, Programming, Software Development > วิธีตรวจจับ Memory Leak โดยง่ายของ Visual C++

วิธีตรวจจับ Memory Leak โดยง่ายของ Visual C++

วิธีนี้จะตรวจจับได้เฉพาะ Memory ที่ Alloc โดยใช้ฟังชั่นของ CRT (C-Runtime) เท่านั้นนะคับ เช่น malloc, realloc, operator new ฯลฯ และจะต้องเป็น Debug Build เท่านั้น หากเป็น Release Build ตัวตรวจจับจะถูกถอดออกอัตโนมัติ ส่วน Memory ที่ Alloc โดยใช้ฟังชั่นนอกเหนือจากนั้น (เช่น HeapAlloc ของ Win32 API) จะไม่สามารถตรวจจับด้วยวิธีนี้ได้ โดยการตรวจจับจะรายงานผลตอนที่โปรแกรมจบการทำงานแล้วผ่านทาง Debug Message ซึ่งดูได้ด้วยโปรแกรม DebugView หรือช่อง Output ของ Visual Studio หาก Debug ใน Visual Studio

วิธีการคือ ให้เรียกฟังชั่น _CrtSetDbgFlag (ต้อง include crtdbg.h เข้ามาก่อน) แบบตัวอย่างด้านล่างตอนที่โปรแกรมเริ่มการทำงาน

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

ตัวอย่างการใช้งานใน DllMain

#include <crtdbg.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /* lpReserved */)
{
	if (DLL_PROCESS_ATTACH == ul_reason_for_call)
	{
		DWORD dwResult, dwBufferSize;
		wchar_t *pszModuleName;

		// Enable C-Runtime memory leak reporter
		_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

		// Get Module Name
		pszModuleName = nullptr;
		dwBufferSize = MAX_PATH / 2;

		do
		{
			free(pszModuleName);
			pszModuleName = reinterpret_cast<wchar_t *>(malloc((dwBufferSize *= 2) * sizeof(wchar_t)));

			dwResult = GetModuleFileName(hModule, pszModuleName, dwBufferSize);
		} while (dwResult == dwBufferSize);

		PathStripPath(pszModuleName);

		g_pszModuleName = pszModuleName;

		// Init WTL
		_Module.Init(NULL, hModule);
	}
	else if (DLL_PROCESS_DETACH == ul_reason_for_call)
	{
		// Free allocated memory
		free(const_cast<wchar_t *>(g_pszConfigDirectory));
		free(const_cast<wchar_t *>(g_pszNppDirectory));
		free(const_cast<wchar_t *>(g_pszModuleName));

		// Terminate WTL
		_Module.Term();
	}

	return TRUE;
}

ตัวอย่างการรายงานผล

Advertisements
Categories: C, C++, Programming, Software Development Tags:
  1. 2012/10/20 at 8:37 AM

    Nice post. I went through the post I found it very informative and useful. Thanks for sharing.

  2. tuinui
    2012/12/06 at 7:09 PM

    หวัดดีครับ ก่อนอื่นต้องขอโทษจริงๆ ไม่รู้จะไปโพสตรงไหน พยายามหาที่ตั้งคำถามใหม่แล้วแต่หาไม่เจอ

    คือพอดีวันนี้ไปเจอ คีย์เวริ์ดนี้มา extern “C” มันเอาไว้ทำงานอย่างไรในโปรแกรมครับ

    ยกตัวอย่างให้ดูหน่อยได้ไหมครับ

    • 2012/12/14 at 2:02 PM

      ไว้ใช้ในกรณีที่ต้องการประกาศฟังชั่นให้สามารถใช้งานได้ในภาษาอื่นๆคับ เช่น C โดยส่วนมากแล้วจะใช้ตอนที่เราสร้าง Shared library คับ (ถ้าบน Windows ก็คือไฟล์ DLL) ตัวอย่างสำหรับฟังชั่นที่ Export จาก DLL

      __declspec(dllexport) extern "C" void __stdcall Init()
      {
      }
      
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s