0

I found a strange behavior when using std::unique_ptr with arrays, please see:

 {
   auto v = std::make_unique<unsigned char []>(10);
   assert(v);
   std::cout << std::hex << v.get() << std::endl; // does not print anything
 }
 {
   auto v = std::make_unique<char []>(10);
   assert(v);
   std::cout << v.get() << std::endl; // does not print anything
 }
 {
   auto v = std::make_unique<uint8_t []>(10);
   assert(v);
   std::cout << v.get() << std::endl; // does not print anything
 }
 {
   auto v = std::make_unique<std::array<uint8_t, 10>>();
   assert(v);
   std::cout << v.get() << std::endl; // works, prints address
 }
 {
   auto v = std::make_unique<uint16_t []>(10);
   assert(v);
   std::cout << v.get() << std::endl; // works, prints address
 }

What's the reason why it doesn't work for byte size arrays? Am I missing something trivial? The above behavior is consistent for C++14 Clang 3.8, gcc 4.9 and 5.2. I read the C++ standard and didn't find something relevant, it would be nice to have an answer that addresses this behavior.

AdvSphere
  • 986
  • 7
  • 15
  • ostreams have special handling for pointers of characters, since that's what makes `std::cout << "hello world\n"` work. The equivalent line for the array versions would be `std::cout << v->data()`. –  Jun 05 '18 at 02:07
  • 1
    if you cast the result of get() to void* it works, too – xaxxon Jun 05 '18 at 02:09
  • I found a *lot* of potential duplicates ... someone should probably sort through them and pick a canonical question. – o11c Jun 05 '18 at 02:10
  • It works with (void*), thanks! – AdvSphere Jun 05 '18 at 02:12
  • It's because `operator<<` treats those type as legacy C strings so will attempt to print them as such. If you want their address, you can cast them to a type that will be *treated* as an address: `std::cout << std::hex << static_cast(v.get()) << std::endl;`. – paxdiablo Jun 05 '18 at 02:14

0 Answers0