It seems that WrapUnique wraps to the wrong type (and hence uses the wrong deleter) for unique_ptr<array[]>. Example:
size_t N = 4;
std::unique_ptr<uint8_t[]> foo(new uint8_t[N]); // This is what I intend to do
std::unique_ptr<uint8_t[]> bar = base::WrapUnique(new uint8_t[N]); // This fails
At least on Mac I get:
error: no viable conversion from 'unique_ptr<unsigned char>' to 'unique_ptr<uint8_t []>'
std::unique_ptr<uint8_t[]> bar = base::WrapUnique(new uint8_t[N]);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/primiano/code/chrome/src/third_party/llvm-build/Release+Asserts/bin/../include/c++/v1/memory:2779:29: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::unique_ptr<unsigned char>' to 'const std::__1::unique_ptr<unsigned char [], std::__1::default_delete<unsigned char []> > &' for 1st argument
class _LIBCPP_TYPE_VIS_ONLY unique_ptr<_Tp[], _Dp>
Note that if I did use *auto* bar this would have silently compiled, but ended up using the wrong deleter (default_deleter<uint8_t> instead of default_deleter<uint8_t[]>, which should translate into delete instead of delete []).
Probably using the wrong deleter works anyways in most implementations (i.e. as long as "operator new" and "operator new[]" both end up calling malloc()) but IMHO is a bit disturbing. The implementation of the global operator new[] could use a different heap. In such a case, using the wrong deleter would cause a crash.
P.S. std::unique_ptr<uint8_t[]> baz = base::MakeUnique<uint8_t[]>(N);
compiles fine (at least on mac) and hence I think that
auto baz = base::MakeUnique<uint8_t[]>(N)
would have done the right thing
Comment 1 by primiano@chromium.org
, Sep 2 2016