placement delete の存在意義について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
MoNoQLoREATOR
記事: 284
登録日時: 13年前
住所: 東京

placement delete の存在意義について

#1

投稿記事 by MoNoQLoREATOR » 11年前

現在 placement delete について調べています。

このサイトを始め、いくつかのサイトで placement delete はメモリ領域にオブジェクトを再配置したい場合に使用するとかかれているのですが、このトピックを読む限り、再配置の際に使用する必要はないようなのですが、実際のところどうなのでしょうか?
上記のトピックを読んだ限りでは、デストラクタさえ呼んでしまえば、再び placement new によってオブジェクトを再配置しても問題ないようですね。
つまり placement delete を呼ぶ必要はない、と。
placement delete を呼ぶと、メモリ領域が開放されるようですが、そもそも明示的に開放する必要はありませんし、むしろ明示的に開放すべきではありませんよね?
ローカル変数に配置していたのならばローカル変数の寿命が尽きるのを待つべきですし、mallocによって確保した領域に配置していたのならばfreeで開放するべきでしょう。
結局のところ placement delete の存在意義はないのではないでしょうか?
むしろ、誤ってdeleteしてしまわないように廃止すべきではないかと思うのですが、どう思われますか?

みなさんのご意見がぜひ聞きたいです。

たかぎ
記事: 328
登録日時: 13年前
住所: 大阪
連絡を取る:

Re: placement delete の存在意義について

#2

投稿記事 by たかぎ » 11年前

operator newを多重定義したときは、必ず対になるoperator deleteも多重定義しなければなりません。
operator new(void*)を多重定義したのであれば、operator delete(void*, void*)も多重定義しなければならないのです。
これは、次のような場合に意味を持ちます。

コード:

class A
{
public:
    A() { throw std::runtime_error("エラー"); }
};

A* ptr = new(&storage) A;
上のコードでは、Aのコンストラクタが例外を送出します。結果として、new式が失敗し、中断されるわけです。
このような場合に、newで割り付けたメモリブロックを解放するためにoperator delete(void*, void*)が呼び出されます。

さて、ここで、operator delete(void*, void*)は、実際にはメモリブロックの解放なんかしないのだから無意味だと感じているのだと思います。
ところが、次のような実装をすることは間違っていません(set_new_handlerで登録したハンドラの呼び出しは省略しています)。

コード:

void* operator new(std::size_t size, void* ptr) throw()
{
    return std::realloc(ptr, size))
}

void operator delete(void* ptr, void*) throw()
{
    std::free(ptr);
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: placement delete の存在意義について

#3

投稿記事 by ISLe » 11年前

コンストラクタの例外についてはplacement deleteを定義しないとコンパイラが警告してくれませんでしたっけ。
VC++だけでしたっけね。

メモリプールを実装して、クラスオブジェクトの前方に管理用のヘッダ情報を配置するような場合も、placement deleteとdeleteを使い分けると便利です。
クラスオブジェクトがぴったり収まるサイズ(引数のサイズ)のメモリしか確保してはいけない道理はないですし。

アバター
MoNoQLoREATOR
記事: 284
登録日時: 13年前
住所: 東京

Re: placement delete の存在意義について

#4

投稿記事 by MoNoQLoREATOR » 11年前

つまり例外が発生した際に placement delete があった方が都合が良いのですね。
そして利用者が placement delete を意識する必要は全く無いという解釈で良さそうです。
解決しました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る