티스토리 뷰

190705-3
 

교육을 받으면서 노트필기 했던 내용을 날것 그대로 업로드합니다.


 
가상메모리
가상메모리 함수 사용
#include <windows.h>
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("BigMemory");
 
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
     ,LPSTR lpszCmdParam,int nCmdShow)
{
   기본 코드 생략
}
 
#define MEGA 1048576
PBYTE stptr=NULL;
TCHAR Status[256]="할당되지 않았습니다";
 
void FreeRecords()
{
    // 할당되어 있던 메모리를 해제한다.
    if (stptr != NULL) {
        if (VirtualFree(stptr, 100*MEGA, MEM_DECOMMIT)==0) { //확정해제
            MessageBox(hWndMain, "메모리 확정 해제 실패","에러",MB_OK);
        }
        if (VirtualFree(stptr, 0, MEM_RELEASE)==0) { // 예약 해제
            MessageBox(hWndMain, "메모리 예약 해제 실패","에러",MB_OK);
        }
        stptr=NULL;
    }
    wsprintf(Status,"할당되지 않았습니다");
    InvalidateRect(hWndMain,NULL,TRUE);
}
 
// 세 개의 포인터 변수가 필요하다.
// stptr:최초 할당된 메모리 공간의 시작 주소
// endptr:현재까지 확정된 메모리 공간의 끝 주소.
// nowptr:현재 사용중인 메모리의 주소
void ReadRecords()
{
    int i, c;
    int RecSize;
    PBYTE nowptr, endptr;
 
    FreeRecords(); // 이미 할당 되어 있으면 제거
 
    // 100M의 주소 공간을 예약한다.
    stptr=(PBYTE)VirtualAlloc(NULL, 100*MEGA, MEM_RESERVE, PAGE_READWRITE);
    //VirtualAlloc : 첫번 째 인수가 NULL 일 경우
    //* 예약할 때 일반적으로 사용하는 함수
    // 100메가 바이트를 예약한다.
 
 
    if (stptr == NULL) {
        MessageBox(hWndMain, "메모리 예약 실패","에러",MB_OK);
        return;
    }
    nowptr=stptr;
    endptr=stptr;
 
    // 최대 100개의 레코드를 읽어들인다.
    c=rand() % 90 + 10; //랜덤발생 최소10 최대 99
    for (i=0;i<c;i++) {
        // 확정된 메모리가 1M 미만이면 1M를 더 확정한다.
        if (endptr-nowptr < MEGA) { // 실제메모리할당끝 - 현재주소
            VirtualAlloc(endptr,MEGA,MEM_COMMIT,PAGE_READWRITE); //진짜 물리메모리를 할당한다.
            //확정할 때는 어디서부터 어디까지 확정할지를 정한다. 1메가만큼 확정할 것이다.
            //확정된 물리메모리는 연속적이지 않을 수 있다.
            endptr+=MEGA; // 확정된 끝 주소를 가리킴
        }
 
        // 10K~1M 사이의 레코드를 읽어들인다.
        RecSize=((rand() % 100)+1)*10240;//10k 를 곱했으니 매우커도 99k 이하
        memset(nowptr,i,RecSize);//메모리 초기화 nowptr 부터 i값으로 RecSize 이만큼 초기화 해라
        nowptr+=RecSize; // 실제 사용된 곳을 가리킨다.
        //실제 다운로드 받을 때 1MB가 남아있다고 가정하고 받고 싶을 경우
    }
 
    wsprintf(Status,"예약:100 메가, 확정:%d 메가, 사용:%d 메가",
        (endptr-stptr)/MEGA,(nowptr-stptr)/MEGA);
    InvalidateRect(hWndMain,NULL,TRUE);
}
 
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    TCHAR *Mes="왼쪽 마우스 버튼:메모리 할당, 오른쪽 마우스 버튼:메모리 해제";
    
    switch (iMessage) {
    case WM_CREATE:
        hWndMain=hWnd;
        srand(GetTickCount());//* 씨드 설정
        return 0;
    case WM_LBUTTONDOWN:
        SetCursor(LoadCursor(NULL,IDC_WAIT)); //*로딩커서
        ReadRecords();
        SetCursor(LoadCursor(NULL,IDC_ARROW));
        return 0;
    case WM_RBUTTONDOWN:
        FreeRecords();
        return 0;
    case WM_PAINT:
        hdc=BeginPaint(hWnd, &ps);
        TextOut(hdc,50,50,Mes,lstrlen(Mes));
        TextOut(hdc,50,80,Status,lstrlen(Status));
        EndPaint(hWnd, &ps);
        return 0;
    case WM_DESTROY:
        FreeRecords();
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
댓글
댓글쓰기 폼