⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 malloc2.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * MALLOC2.CPP
 * C++ Malloc Demonstration Chapter 2
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "malloc2.h"


/*
 * WinMain
 *
 * Purpose:
 *  Main entry point of application.
 */

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
    , LPSTR pszCmdLine, int nCmdShow)
    {
    MSG         msg;
    PAPP        pApp;
    DWORD       dwVer;
    HRESULT     hr;

    SETMESSAGEQUEUE;

    //Make sure COM is the right version
    dwVer=CoBuildVersion();

    if (rmm!=HIWORD(dwVer))
        return 0;

    //Initialize OLE
    hr=CoInitialize(NULL);

    if (FAILED(hr))
        return 0;

    pApp=new CApp(hInst, hInstPrev, nCmdShow);

    if (NULL!=pApp)
        {
        if (pApp->Init())
            {
            while (GetMessage(&msg, NULL, 0,0 ))
                {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
                }
            }

        delete pApp;
        }

    //Only call this if CoInitialize worked
    CoUninitialize();
    return 0;
    }





/*
 * MallocWndProc
 *
 * Purpose:
 *  Standard window class procedure.
 */

LRESULT APIENTRY MallocWndProc(HWND hWnd, UINT iMsg
    , WPARAM wParam, LPARAM lParam)
    {
    PAPP        pApp;
    ULONG       cb;
    UINT        i;
    BOOL        fResult;

    pApp=(PAPP)GetWindowLong(hWnd, MALLOCWL_STRUCTURE);

    switch (iMsg)
        {
        case WM_NCCREATE:
            pApp=(PAPP)(((LPCREATESTRUCT)lParam)->lpCreateParams);
            SetWindowLong(hWnd, MALLOCWL_STRUCTURE, (LONG)pApp);
            return (DefWindowProc(hWnd, iMsg, wParam, lParam));

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
                {
                case IDM_COGETMALLOC:
                    pApp->GetAllocator();
                    break;


                case IDM_RELEASE:
                    if (!pApp->HaveAllocator())
                        break;

                    pApp->FreeAllocations(TRUE);
                    pApp->Message(TEXT("Release complete"));
                    break;


                case IDM_ALLOC:
                    if (!pApp->HaveAllocator())
                        break;

                    fResult=pApp->DoAllocations(FALSE);

                    pApp->Message(fResult ? TEXT("Alloc succeeded")
                        : TEXT("Alloc failed"));

                    break;


                case IDM_FREE:
                    if (!pApp->HaveAllocations())
                        break;

                    pApp->FreeAllocations(FALSE);
                    pApp->Message(TEXT("Free complete"));
                    break;


                case IDM_REALLOC:
                    if (!pApp->HaveAllocator())
                        break;

                    fResult=pApp->DoAllocations(TRUE);

                    pApp->Message(fResult ? TEXT("Realloc succeeded")
                        : TEXT("Realloc failed"));

                    break;


                case IDM_GETSIZE:
                    if (!pApp->HaveAllocations())
                        break;

                    fResult=TRUE;

                    for (i=0; i < CALLOCS; i++)
                        {
                        cb=pApp->m_pIMalloc->GetSize(pApp->m_rgpv[i]);

                        /*
                         * We test that the size is *at least*
                         * what we wanted.
                         */
                        fResult &= (pApp->m_rgcb[i] <= cb);
                        }

                    pApp->Message(fResult ? TEXT("Sizes matched")
                        : TEXT("Sizes mismatch"));

                    break;


                case IDM_DIDALLOC:
                    if (!pApp->HaveAllocations())
                        break;

                    /*
                     * DidAlloc may return -1 if it does not know
                     * whether or not it actually allocated
                     * something.  In that case we just blindly
                     * & in a -1 with no affect.
                     */

                    fResult=(BOOL)-1;

                    for (i=0; i < CALLOCS; i++)
                        {
                        fResult &= pApp->m_pIMalloc
                            ->DidAlloc(pApp->m_rgpv[i]);
                        }

                    if (0==fResult)
                        pApp->Message(TEXT("DidAlloc is FALSE"));

                    if (1==fResult)
                        pApp->Message(TEXT("DidAlloc is TRUE"));

                    if (-1==fResult)
                        pApp->Message(TEXT("DidAlloc is unknown"));

                    break;


                case IDM_HEAPMINIMIZE:
                    if (!pApp->HaveAllocator())
                        break;

                    pApp->m_pIMalloc->HeapMinimize();
                    pApp->Message(TEXT("HeapMinimize finished"));
                    break;


                case IDM_EXIT:
                    PostMessage(hWnd, WM_CLOSE, 0, 0L);
                    break;
                }
            break;

        default:
            return (DefWindowProc(hWnd, iMsg, wParam, lParam));
        }

    return 0L;
    }





/*
 * CApp::CApp
 * CApp::~CApp
 *
 * Constructor Parameters: (from WinMain)
 *  hInst           HINSTANCE of the application.
 *  hInstPrev       HINSTANCE of a previous instance.
 *  nCmdShow        UINT specifying how to show the app window.
 */

CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
    , UINT nCmdShow)
    {
    UINT        i;
    ULONG       cb;

    m_hInst       =hInst;
    m_hInstPrev   =hInstPrev;
    m_nCmdShow    =nCmdShow;

    m_hWnd        =NULL;
    m_pIMalloc    =NULL;
    m_fAllocated  =FALSE;

    //100 is arbitrary.  IMalloc can handle larger.
    cb=100;

    for (i=0; i < CALLOCS; i++)
        {
        m_rgcb[i]=cb;
        m_rgpv[i]=NULL;

        cb*=2;
        }

    return;
    }



CApp::~CApp(void)
    {
    FreeAllocations(TRUE);
    return;
    }





/*
 * CApp::Init
 *
 * Purpose:
 *  Initializes an CApp object by registering window classes,
 *  creating the main window, and doing anything else prone to
 *  failure.  If this function fails the caller should insure
 *  that the destructor is called.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  BOOL            TRUE if successful, FALSE otherwise.
 */

BOOL CApp::Init(void)
    {
    WNDCLASS    wc;

    if (!m_hInstPrev)
        {
        wc.style          = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc    = MallocWndProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = CBWNDEXTRA;
        wc.hInstance      = m_hInst;
        wc.hIcon          = LoadIcon(m_hInst, TEXT("Icon"));
        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
        wc.lpszClassName  = TEXT("MALLOC2");

        if (!RegisterClass(&wc))
            return FALSE;
        }

    m_hWnd=CreateWindow(TEXT("MALLOC2"), TEXT("C++ Malloc Demo")
        , WS_OVERLAPPEDWINDOW, 35, 35, 350, 250, NULL, NULL
        , m_hInst, this);

    if (NULL==m_hWnd)
        return FALSE;

    ShowWindow(m_hWnd, m_nCmdShow);
    UpdateWindow(m_hWnd);

    return TRUE;
    }




/*
 * CApp::GetAllocator
 *
 * Purpose:
 *  Retrieves the current allocator.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  None
 */

void CApp::GetAllocator(void)
    {
    HRESULT     hr;
    TCHAR       szTemp[80];

    //This also releases m_pIMalloc
    FreeAllocations(TRUE);

    hr=CoGetMalloc(MEMCTX_TASK, &m_pIMalloc);

    wsprintf(szTemp, TEXT("CoGetMalloc %s")
        , SUCCEEDED(hr) ? TEXT("succeeded") : TEXT("failed"));

    Message(szTemp);
    return;
    }



/*
 * CApp::HaveAllocator
 *
 * Purpose:
 *  Checks if there's a valid allocator and displays a
 *  message if not.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  BOOL            TRUE if there is an allocator, FALSE otherwise.
 */

BOOL CApp::HaveAllocator(void)
    {
    if (NULL==m_pIMalloc)
        {
        Message(TEXT("Create the allocator first"));
        return FALSE;
        }

    return TRUE;
    }




/*
 * CApp::DoAllocations
 *
 * Purpose:
 *  Centralized place to clean up allocations made on
 *  the current IMalloc.
 *
 * Parameters:
 *  fRelease        BOOL indicating if we're to
 *                  IMalloc::Release as well.
 *
 * Return Value:
 *  BOOL            TRUE if all allocations succeeded.
 */

BOOL CApp::DoAllocations(BOOL fRealloc)
    {
    UINT        i;
    ULONG       iByte;
    BOOL        fResult=TRUE;
    ULONG       cb;
    LPVOID      pv;

    if (!fRealloc)
        FreeAllocations(FALSE);

    for (i=0; i < CALLOCS; i++)
        {
        //cb is set in the code below for later initialization
        if (fRealloc)
            {
            m_rgcb[i]+=128;
            cb=m_rgcb[i];

            //Old memory is not freed if Realloc fails
            pv=m_pIMalloc->Realloc(m_rgpv[i], cb);
            }
        else
            {
            cb=m_rgcb[i];
            pv=m_pIMalloc->Alloc(cb);
            }

        m_rgpv[i]=pv;

        //Fill the memory with letters.
        if (NULL!=pv)
            {
            LPBYTE  pb=(LPBYTE)pv;

            for (iByte=0; iByte < cb; iByte++)
                *pb++=('a'+i);
            }

        fResult &= (NULL!=pv);
        }

    m_fAllocated=fResult;

    //Clean up whatever we might have allocated
    if (!fResult)
        FreeAllocations(FALSE);

    return fResult;
    }




/*
 * CApp::HaveAllocations
 *
 * Purpose:
 *  Checks if we have allocated memory from the current allocator,
 *  displaying a message if not.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  BOOL            TRUE if there are allocations, FALSE otherwise.
 */

BOOL CApp::HaveAllocations(void)
    {
    if (!HaveAllocator())
        return FALSE;

    if (!m_fAllocated)
        {
        Message(TEXT("Choose Alloc first"));
        return FALSE;
        }

    return TRUE;
    }






/*
 * CApp::FreeAllocations
 *
 * Purpose:
 *  Centralized place to clean up allocations made on
 *  the current IMalloc.
 *
 * Parameters:
 *  fRelease        BOOL indicating if we're to
 *                  IMalloc::Release as well.
 *
 * Return Value:
 *  None
 */

void CApp::FreeAllocations(BOOL fRelease)
    {
    UINT    i;

    if (NULL==m_pIMalloc)
        return;

    if (m_fAllocated)
        {
        for (i=0; i < CALLOCS; i++)
            {
            if (NULL!=m_rgpv[i])
                m_pIMalloc->Free(m_rgpv[i]);

            m_rgpv[i]=NULL;
            }

        m_fAllocated=FALSE;
        }

    if (fRelease)
        {
        m_pIMalloc->Release();
        m_pIMalloc=NULL;
        }

    return;
    }





/*
 * CApp::Message
 *
 * Purpose:
 *  Displays a message in the client area of the window.  This is
 *  just to centralize the call to simpify other code.
 *
 * Parameters:
 *  psz             LPTSTR to the string to display.
 *
 * Return Value:
 *  None
 */

void CApp::Message(LPTSTR psz)
    {
    HDC     hDC;
    RECT    rc;

    hDC=GetDC(m_hWnd);
    GetClientRect(m_hWnd, &rc);

    SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
    SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));

    /*
     * We'll just be sloppy and clear the whole window as
     * well as write the string with one ExtTextOut call.
     * No word wrapping here...
     */

    ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, psz, lstrlen(psz), NULL);
    ReleaseDC(m_hWnd, hDC);
    return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -