혹시나 싶어서 여기 게시판에서 검색하니 나오지 않더군요..
모르시는 분들 계실까봐 적어봅니다...
보통 잘못된 메모리 영역에 쓰기를 하는 경우(memory corruption) 오류가 즉시 발생하지 않습니다..
이런 오류를 잡기가 참으로 난감한데요..
그럴 때 _ASSERT(_CrtCheckMemory()); 를 많이 사용하셨을 겁니다.
-------------------------------------------------
_CrtCheckMemory()에 대한 사용법은.. 아실거라고 가정하고..
DCRT를 사용하기 위한 준비 작업만 간단하게 적어봅니다.
//stdafx.h 제일 처음에 선언
#define _CRTDBG_MAP_ALLOC
//stdafx.h 제일 마지막에 선언
#include <crtdbg.h>
// main() 제일 처음에 선언
_CrtSetDbgFlag(
_CRTDBG_CHECK_ALWAYS_DF
|_CRTDBG_LEAK_CHECK_DF
|_CRTDBG_ALLOC_MEM_DF
|_CRTDBG_DELAY_FREE_MEM_DF
);
-------------------------------------------------------
그런데 _CrtCheckMemory()를 사용해서 커럽션 발생 유무는 확인 할 수 있어도
어느 부분이 문제인지는 알 수 없습니다.
결국 _ASSERT(_CrtCheckMemory()); 를 의심되는 코드에 넣어가면서 범위를 좁히게 되는데요..
그럼에도 불구하고 문제를 해결하기 난감한 상황이 올 수 있습니다.
그럴 때 아래와 같은 코드를 사용하면 효험을 볼 수 있습니다.
_ASSERT(_CrtIsMemoryBlock(buffer, size, NULL,NULL,NULL));
_CrtIsMemoryBlock()는 지정된 메모리 영역이 올바른 힙 메모리인지 검증합니다.
스택 메모리나.. 이런 것은 안 됩니다. 힙만 됩니다.
그래서.. IOCP와 같은 비동기로 메모리에 쓰기 요청을 하기 전에 위와 같은 코드로 검증을 하면..
커럽션이 발생할 것인지 미리 알 수 있습니다.
상큼하게..
void Transfer::PreRequest(BYTE* buffer, int size)
{
_ASSERT(_CrtIsMemoryBlock(buffer, size, NULL,NULL,NULL));
}
위와 같이 전달 받은 포인터로 작업을 하는 함수의 제일 상단에 검증하는 코드를 넣어주면...
뭔가 있어 보입니다... ^^
------------------------------------------------------------
퇴근 시간이 조금 남아서 예제 하나 만들어 봤습니다.
진작 만들걸.. 하는 후회가 듭니다... T_T
#define _CRTDBG_MAP_ALLOC
#include <tchar.h>
#include <memory>
#include <crtdbg.h>
int _tmain(int argc, _TCHAR* argv[])
{
_CrtSetDbgFlag(
_CRTDBG_CHECK_ALWAYS_DF
|_CRTDBG_LEAK_CHECK_DF
|_CRTDBG_ALLOC_MEM_DF
|_CRTDBG_DELAY_FREE_MEM_DF
);
int* p=new int[10];
const int size=sizeof(int)*10;
//p[9]까지유효하기때문에p[10]에무언가를기록하면
//Memory Corruption이다. 커럽션이발생한이후에
//_CrtCheckMemory()를실행하면false를리턴한다.
_ASSERT(true==_CrtCheckMemory());
p[10]=0;
_ASSERT(false==_CrtCheckMemory());
//할당한후_CrtIsMemoryBlock로영역을체크하면true를리턴
_ASSERT(true==_CrtIsMemoryBlock((const void *)p, size, NULL, NULL, NULL));
//p를delete 한후에_CrtIsMemoryBlock로영역을체크하면
//올바르지않은힙영역이기때문에false가리턴된다.
delete[] p;
_ASSERT(false==_CrtIsMemoryBlock((const void *)p, size, NULL, NULL, NULL));
return 0;
}
'NativeCode > api' 카테고리의 다른 글
IpHlpApi MSDN (0) | 2010.07.04 |
---|---|
SendARP (0) | 2010.07.03 |
WSAGetLastError() (0) | 2010.04.06 |
Sock 정보들 (0) | 2010.04.04 |
소켓 옵션 (0) | 2010.04.01 |