3. N3495
IV
提案インターフェース
2014/1/30
template<typename Alloc>
class std::allocator_traits {
public:
リサイズしたいメモリのポインタ
... /* Existing definition. */
static pointer
alloc_resize(Alloc& a, pointer p, size_type n_cur, size_type n_new)
{
現在の(変更前の)サイズ
変更後のサイズ
/*
* p, having n_cur elements,
reallocのようにメモリの移動は行わない
* would change to having n_new elements.
* If the allocator does not support this,
* std::bad_alloc() is thrown.
要素を増やすことができない場合は、
std::bad_alloc()をthrow
*
* (p, n_cur) must refer to a previous allocation,
* or the behaviour is undefined.
前回の確保に対応していないのを渡したら
*
undefined behavior
* This function is implemented as:
* a.alloc_resize(p, n_cur, n_new) iff implemented by Alloc,
* or as
* throw std::bad_alloc() otherwise.
*/
return p;
実装されていない場合はstd::bad_alloc()をthrow
}
};
3
7. V
N3495
この機能の追加について
• Actually a big counter-argument, which I suspect is
the cause for this not being in the c++11 standard in
the first place:
– CON: exact semantics not supported by the C standard,
nor in new[]/delete[] operators, making an
implementation for std::allocator hard.
• C標準では、このsemacticsがサポートされていない
reallocで、メモリアドレスそのままで伸長できない場合、メモリの移動が発生してしま
う
• new[], delete[] でもリサイズはできない
• std::allocatorの実装が大変である
伸長できないとき、null ポインタを返すような、resizeみたいなものがあればいいのかな
後ほど、深掘りして議論する
2014/1/30
7
8. N3495
V
【参考】libsupc++ new_op.cc の実装
using std::new_handler;
using std::bad_alloc;
#if _GLIBCXX_HOSTED
using std::malloc;
#else
// A freestanding C runtime may not provide "malloc" -- but there is no
// other reasonable way to implement "operator new".
extern "C" void *malloc (std::size_t);
#endif
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
p = (void *) malloc (sz);
while (p == 0)
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
p = (void *) malloc (sz);
}
return p;
}
2014/1/30
8
13. N3495
誤り指摘
• VI: Technical specifications XXX not the actual
wording in the final standard, mostly intended to
illustrate the proposed semantics. std::allocator
may or may not implement
std::allocator<T>::alloc_resize(pointer p, size_type
n_cur, size_type n_new). If the combination (p,
n_cur) does not reflect an existing allocation, an
std::invalid_argument exception will be thrown.
undefined behaviorの誤りだと思われる。
2014/1/30
13