プログラミングメモ →目次


オペレーター new delete のオーバーロード

 オペレーター new delete のオーバーロードで、メモリの管理、ワイルドポインターの防止、メモリのリークの監視などに役に立ちます。

例として、newで割り当てたメモリのポインターを配列に保存しておき、ポインターの有効性(ワイルドポインターであるか)をチェックする関数 bool is_valid(void * address)を作成し、メモリリークの確認に使える関数 bool is_holding()を作成します。

オーバーロード方法を示すプログラム:

// address set
#define 10 100
void* address_set[10] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};

// new
void * operator new(size_t size)
{
    void * address = malloc(size);
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] == NULL) 
        {
            address_set[i] = address;
            break;
        }
    }
    return address;
}

// new []
void * operator new[](size_t size)
{
    void * address = malloc(size);
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] == NULL) 
        {
            address_set[i] = address;
            break;
        }
    }
    return address;
}

// delete
void operator delete(void * address)
{
    if(address == 0)
        return;
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] == address) 
        {
            address_set[i] = NULL;
            break;
        }
    }
    free(address);
}

// delete []
void operator delete[](void * address)
{
    if(address == 0)
       return;
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] == address) 
        {
            address_set[i] = NULL;
            break;
        }
    }
    free(address);
}

// is_valid
bool is_valid(void * address)
{
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] == address) 
            return true;
    }
    return false;
}

// is_holding
bool is_holding()
{
    for (int i = 0; i < 10; i ++) 
    {
        if (address_set[i] != NULL) 
             return true;
    }
    return false;
}

ポインターがワイルドポインターかどうかをチェックする例です:


// MFCを利用する場合は、newの再定義をやめる!
//#ifdef _DEBUG
//#define new DEBUG_NEW
//#endif

bool is_valid(void * address);

void CTestDlg::OnBnClickedButton1()
{
    CString* pStr = new CString(L"abc");
    if (is_valid(pStr)) // 有効
    {
         * pStr = L"def";
    }
    delete pStr;
    if (is_valid(pStr)) // 無効
    {
        * pStr = L"xyz";
    }
}