New issue
Advanced search Search tips

Issue 643696 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Sep 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

base::WrapUnique uses the wrong deleter for array types

Project Member Reported by primiano@chromium.org, Sep 2 2016

Issue description

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
 
Summary: base::WrapUnique uses the wrong deleter for array types (was: base::WrapUnique uses the default deleter for array types)
Status: WontFix (was: Untriaged)
Ya, this is why MakeUnique is good. There's a comment on here https://cs.chromium.org/chromium/src/base/memory/ptr_util.h?rcl=0&l=15 which was originally much stronger IIRC but in general I think this is why std::make_unique was invented. We can't really change WrapUnique to do anything better so Im not sure what action to take here.

Sign in to add a comment