2017-12-12 14 views
0

Allocatorが標準ライブラリアロケータインターフェイスに準拠している場合は、ヌルポインタを使用してstd::allocator_traits<Allocator>::deallocateを呼び出しても安全ですか? Allocatorstd::allocator(最終的にはdeleteになるため)だとわかっていますが、Allocatorがクライアント提供クラスの場合はどうなりますか?私は明示的なチェックをしなければならないのですか? の記事Allocator conceptにはそのような保証が記載されていないので、答えは「はい」だと思いますが、私は確信しています。nullポインタでallocator_traits :: deallocateを呼び出す

質問の動機を少し与えるために、変数pがバッファへのポインタを保持すると仮定されているユースケースを想像していますが、何らかの理由でバッファがありました(最初はnullptrに設定されています)。最初の場所に割り当てられないので、pはヌルポインタのままです。

+0

ストレージへのポインタがnullptrであり、オブジェクトの数が> 0であることを意味しますか? –

+0

オブジェクトの数がゼロかどうかによって答えが変わりますか? –

+0

私の印象は、問題のアロケータが割り当てるためにnullptrを返す場合、nullptrも同様に割り当てを解除するための有効な引数であることです。しかし、オブジェクトの数が0より大きい場合、なぜnullptrを返すのか想像できません。 –

答えて

2

最初に、std::allocator<T>::deallocate(T* p, std::size_t)ではなく、となります。delete pとなります。その代わりに23.10.9.1 [allocator.members]パラグラフ7に従ってoperator delete(p)を呼び出します。代わりに、同項のパラグラフ5の要件は、std::allocator<T>::allocate()からpを取得したものとします。この関数はヌルポインタを返すことはできません。すなわち、std::allocator<T>::deallocate()はヌルポイントを受け入れません。アロケータのコンセプトがNULLポインタを渡すことができれば、std::allocator<T>はそのコンセプトをモデル化しないので驚くべきことです。

表31のアロケータの概念は、同様に、a.deallocate(p)への引数がa.allocate()から得られたことを要求します。 a.allocate(n)の仕様では、常にnオブジェクトに十分なメモリが返されるため(唯一の例外は例外によるものです)、NULLポインタに対処することはできません。したがって、a.deallocate()はNULLポインタに対応できません。

質問は約allocator_traits<...>::deallocate()でした。しかし、23.10.8.2 [allocator.traits.members]パラグラフ3によれば、この関数は単にアロケータのdeallocate()関数に委譲します。つまり、ヌルポインタはそこでは有効な引数ではありません。

+0

与えられた数値オブジェクトが0のとき、Allocator :: allocateが返すものは未定義です。その "未指定"は、実装(またはカスタムアロケータ)が指定する有効な値を意味します。それはnullptrすることはできませんか? –

+0

@ÖöTiib:アロケータの実装は、オブジェクトのサイズがゼロのシーケンスの表現として 'nullptr'を使用することを選択できます。しかし、そうすることは保証されていません。つまり、ユーザーは 'nullptr'が有効な表現であると仮定することはできません。 –

関連する問題