operator new/delete 解答ページ | Programming Place Plus C++編【言語解説】 第36章

トップページC++編

C++編で扱っている C++ は 2003年に登場した C++03 という、とても古いバージョンのものです。C++ はその後、C++11 -> C++14 -> C++17 -> C++20 -> C++23 と更新されています。
なかでも C++11 での更新は非常に大きなものであり、これから C++ の学習を始めるのなら、C++11 よりも古いバージョンを対象にするべきではありません。特に事情がないなら、新しい C++ を学んでください。 当サイトでは、C++14 をベースにした新C++編を作成中です。

問題①

問題① 配置構文new が失敗したとき、operator delete が呼び出されていることを確認するプログラムを作成してください。


operator new が失敗した場合には、メモリ確保自体が行えていないので operator delete は呼び出されません。operator delete が呼び出される様を確認するには、オブジェクトの生成の過程で失敗させる必要があります。そのためには、コンストラクタから例外を送出します。

#include <iostream>
#include <new>

class MyClass {
public:
    MyClass()
    {
        std::cout << "constructor" << std::endl;
        throw "";
    }

    ~MyClass()
    {
        std::cout << "destructor" << std::endl;
    }

    static void* operator new(std::size_t size, void* where) throw()
    {
        std::cout << "new" << std::endl;
        return ::operator new(size, where);
    }
    static void operator delete(void* p, void* where) throw()
    {
        std::cout << "delete" << std::endl;
        ::operator delete(p, where);
    }
};

int main()
{
    char buf[sizeof(MyClass)];

    try {
        MyClass* p = new(buf) MyClass();
        p->~MyClass();
    }
    catch (...) {
    }
}

実行結果:

new
constructor
delete

なお、問題とは関係がないので省略していますが、本来なら、本編で取り上げているように、クラス専用の operartor new/delete を定義するのなら、すべてのタイプの operator new/delete を定義するようにしてください。

問題②

問題② 確保済みの領域のメモリアドレスと、メモリ確保時に出力する任意の文字列を渡せるような placement new を定義してください。


#include <iostream>
#include <new>

class MyClass {
public:
    ~MyClass() {}

    static void* operator new(std::size_t size, void* where, const char* msg) throw()
    {
        std::cout << "new: " << msg << std::endl;
        return ::operator new(size, where);
    }
    static void operator delete(void* p, void* where, const char* msg) throw()
    {
        std::cout << "delete: " << msg << std::endl;
        ::operator delete(p, where);
    }
};

int main()
{
    char buf[sizeof(MyClass)];

    MyClass* p = new(buf, "first time") MyClass();
    p->~MyClass();

    p = new(buf, "second time") MyClass();
    p->~MyClass();
}

実行結果:

new: first time
new: second time

operator new/delete の引数が2つ増え、new演算子使用時に new(~) の ~ の部分に指定する引数も2つ増えます。operator delete の方も定義することを忘れないようにしてください。

なお、問題とは関係がないので省略していますが、本来なら、本編で取り上げているように、クラス専用の operartor new/delete を定義するのなら、すべてのタイプの operator new/delete を定義するようにしてください。


参考リンク

更新履歴

’2017/2/22 新規作成。



第36章のメインページへ

C++編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る