配置new

提供: C++入門
移動: 案内検索
スポンサーリンク

配置new (placement new, プレイスメントnew)とは、もともとは、インスタンスを特定のメモリアドレスに配置するための機能です。

読み方

配置new
はいち にゅー
placement new
ぷれいすめんと にゅー
プレイスメント new
ぷれいすめんと にゅー

概要

new演算子には、以下のプロトタイプが宣言されています。 /usr/include/c++/v1/tr1/new からの抜粋です。

void* operator new(std::size_t size);                                   // replaceable
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable
void* operator new[](std::size_t size);                                 // replaceable
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
void* operator new  (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;

配置newでは、あらかじめ用意したメモリに対して、インスタンスを割り当てることができます。 なお、明示的にデストラクタを呼び出す必要があります。

void *p = std::malloc(sizeof (Hoge) );
Hoge *obj = new(p) Hoge;
 
// obj を使用する
 
obj->~Hoge();
std::free(p);

宣言で何が違うのか、もう少し見比べてみましょう。 new演算子の通常の使い方は、このような呼び出し方になります。

Hoge *obj = new Hoge;
Hoge *obj = new Hoge(コンストラクタの引数);

配置newの場合は、以下の呼び出しになります。

Hoge *obj = new(ptr) Hoge;
Hoge *obj = new(ptr) Hoge(コンストラクタの引数);

replace_new1.cpp の例

簡単な配置newの例です。

ソースコード replace_new1.cpp

mallocで確保したメモリのアドレスとobjに格納されているアドレスをstd::hexで表示すると同じアドレスになっていることが確認できます。

/*
 * replace_new1.cpp
 * Copyright (C) 2014 kaoru <kaoru@bsd>
 */
 
#include <iostream>
using namespace std;
class Hoge {
        public:
                Hoge(){ cout<< __PRETTY_FUNCTION__ << endl;}
                virtual ~Hoge(){ cout<< __PRETTY_FUNCTION__ << endl;}
};
 
int main(int argc, char const* argv[])
{
        void *p = std::malloc(sizeof (Hoge) );
        Hoge *obj = new(p) Hoge;
 
        cout << hex << p << endl;
        cout << hex << obj << endl;
 
        obj->~Hoge();
        std::free(p);
        return 0;
}

コンパイル

c++  replace_new1.cpp -o replace_new1

実行例

このように、任意のアドレスにインスタンスを配置できました。

% ./replace_new1
Hoge::Hoge()
0x801c06058
0x801c06058
virtual Hoge::~Hoge()

関連項目




スポンサーリンク