/* worksize.c :                coded by isaku@pb4.so-net.ne.jp 2008
C/C++言語でプログラムのメモリ使用量を得る

●概要
デバッグ時に、プログラムがメモリリークを起こしているかどうかを
確認するために、プログラムが消費しているメモリ量を知りたいことが
ある。そんなときに、この関数を使う。
ただし、Windows 95系では常に 0 が返る。

●単純な方法

#include <psapi.h>
int WorkSize(void) {
    PROCESS_MEMORY_COUNTERS info;
    GetProcessMemoryInfo(GetCurrentProcess(),&info,sizeof info);
    return info.WorkingSetSize;
}

●単純な方法の問題点

・Visual C++ 6.0 ではコンパイルできない
Visual C++ 6.0 には psapi.h と psapi.lib がない。

・Window 95系でプログラムを起動できない
Windows 95系には psapi.dll がない。
従って、単純な方法を利用したソースを Borland C++ 5.1 や、
Visual C++ 2002 以降でコンパイルして作ったプログラムを
Windows 95系で実行しようとすると main() や WinMain() に
制御が渡る前にメッセージボックスが現れて終了してしまう。

下にある WorkSize() 関数を使えば Windows 95系の場合、
メモリ使用量を得ることはできない(0が返る)が、
プログラムの実行はできる。

*/
#include <windows.h>

int WorkSize(void) {
    typedef struct {
        DWORD  cb;
        DWORD  PageFaultCount;
        SIZE_T PeakWorkingSetSize;
        SIZE_T WorkingSetSize;
        SIZE_T QuotaPeakPagedPoolUsage;
        SIZE_T QuotaPagedPoolUsage;
        SIZE_T QuotaPeakNonPagedPoolUsage;
        SIZE_T QuotaNonPagedPoolUsage;
        SIZE_T PagefileUsage;
        SIZE_T PeakPagefileUsage;
    } info_t;
    typedef BOOL(WINAPI*func_t)(HANDLE,info_t*,DWORD);
    static func_t func; static enum { FIRST,OK,ERR } flag;
    static HANDLE proc; info_t info; HINSTANCE dll;
    if (flag==FIRST) {
        if ((dll=LoadLibraryA("psapi"))==0) { flag=ERR; return 0; }
        func=(func_t)GetProcAddress(dll,"GetProcessMemoryInfo");
        if (func==0) { flag=ERR; return 0; }
        proc=GetCurrentProcess(); flag=OK;
    }
    if (flag==ERR) return 0;
    func(proc,&info,sizeof info); return(int)info.WorkingSetSize;
}