これは実装固有のビットですが、その一部は基本的なようです。std :: unique_ptrのためのメモリ効率の良いカスタムディテクタ?
標準ライブラリで何かが欠けているはずです。
問題はこれです:
私は[値はmalloc()
を経由して割り当てられるため]そのデリータfree()
あるstd::unique_ptr
を実装したい
のオプションの多くは、もちろん、あります。これを行う方法は (少なくともg ++ 4.8.4ではx86-64)、メモリ使用の意味が異なるようです。
例: 方法1:しかし
std::unique_ptr<char, std::function<void(void*)>> ptr_a(malloc(10), free);
、 sizeof(ptr_a)
== 40バイト(ボイド* 8、STD 32 ::機能<>)
方法2:
std::unique_ptr<void, void (*)(void*)> ptr_b(malloc(10), free);
多少良くなって、 sizeof(ptr_b)
== 16バイト(void *の場合8、裸の場合は8)イオンポインタ])
方法3:
template <void (*T)(void*)>
class Caller {
public:
void operator()(void* arg) {
return T(arg);
}
};
std::unique_ptr<void, Caller<free>> ptr_c(malloc(10));`
この時点で、sizeof(ptr_c)
== 8バイト(最小可能) - しかし、私は定型ほとんど純粋だクラスを導入しなければならなかった(とき、図示のように、容易にテンプレート化される)。
これは、このような単純なパターンのようです - STLには何の要素がありますか?Caller<>
は何ですか?
もちろん、g ++は簡単な型でdeleteを呼び出すときにfree()と表示されますが、これは標準では保証されていないようです(他に何もない場合、new/deleteはデフォルトの割り当て/ deallocation関数を呼び出すと、default_deleteは置き換えdeleteを呼び出します)。
また、純粋なCライブラリに割り当てられたオブジェクトのリリースが、単純な関数呼び出しではなく、単純な関数で実装される場合もあります。このような割り当て/解放関数をクラスでラップして、std :: unique_ptrが正しくかつ効率的に呼び出されるようにするのは、ちょっと面倒なようです。何かが欠けていると思います(現代のC++仕様のほとんど非常によく考えられているように思われる)。あなたの第三の選択肢として
auto free_lmbd = [](void *_ptr) { free (_ptr);};
std::unique_ptr<void, decltype (free_lmbd)> ptr {malloc(10), free_lmbd};
も(少なくとも私のコンピュータ上で)8つのバイトを持っていますが、同じ:
このオブジェクトは、コンパイルユニット間でODRに違反することなく、周りに渡すことが困難となります。 – Yakk
はい、あなたは正しいです。 – Hakes