C++のoperator new/operator deleteについて

C++のoperator new/operator deleteについて

Posted at April 25,2017 12:03 AM
Tag:[C/C++]

C++のoperator new/operator deleteについて紹介します。

1.サンプル

まず最初にサンプルをご覧ください。

#include <cstdio>
#include <cstdlib>
 
class Test {
 
private:
 
    int number;
 
public:
 
    Test(int num) {
        number = num;
        std::printf("constructor: %d\n", number);
    }
 
    ~Test() {
        std::printf("destructor\n");
    }
 
    void* operator new(std::size_t sz) {
        std::printf("operator new: %zu\n",sz);
        return std::malloc(sz);
    }
 
    void operator delete(void* ptr) {
        std::printf("operator delete: %p\n", ptr);
        std::free(ptr);
    }
};
 
int main() {
     Test* test = new Test(100);
     delete test;
}

このサンプルを元にoperator new/operator deleteについて紹介します。

2.operator new/operator deleteとは

operator new/operator deleteは、コンストラクタ起動時、特定のエリアからメモリを確保(または解放)するための仕組みです。

通常のコンストラクタは、

  • メモリの割当
  • オブジェクトの構築

という2つの動作を行いますが、operator newはメモリの割り当てを実行します。

サンプルでは下記の部分になります。

void* operator new(std::size_t sz) {
    std::printf("operator new: %zu\n",sz);
    return std::malloc(sz);
}

引数の"size_t"はC++の仕様で決められたもので、オブジェクトのサイズになります。

ユーザーがコンストラクタ起動時にパラメータにサイズを指定する必要はありません(おそらくコンパイラ時にオブジェクトのサイズが分かる)。

また、戻り値の型は"void *"です。

operator deleteは下記の部分です。

void operator delete(void* ptr) {
    std::printf("operator delete: %p\n", ptr);
    std::free(ptr);
}

引数は確保したアドレスになります。こちらもデストラクタ起動時のパラメータに指定する必要はありません。

3.newとoperator newの違い

operator newはnewのオーバーロード(引数や戻り値が異なるが名称が同一のメソッドを複数定義すること)ですが、operator newとnewが存在する場合、順番に起動されることから、個人的には通常のオーバーロードとは動作が異なる気がします。

具体的には、ユーザープログラムがコンストラクタを実行すると、先にoperator newが起動されてメモリ確保等を行い、その後通常のコンストラクタが起動するようになっています。

デストラクタの動作はその逆で、先に通常のデストラクタが起動され、operator deleteが動作してメモリ解放を行います。

サンプルで説明すると、mainに記述した、

Test* test = new Test(100);

が実行されることで、最初に、

void* operator new(std::size_t sz) { ... }

が起動してmallocでメモリを確保し、その後

Test(int num) { ... }

が起動します。

サンプルの実行結果は下記のようになります。

operator new: 4
constructor: 100
address: 0x12a9010
destructor
operator delete

「4」というのは、クラスで定義した変数

int number;

のサイズになります。

4.参考サイト

参考サイトは下記です。ありがとうございました。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)