Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shared_ptr with char*

Tags:

c++

c++11

I can not create:

shared_ptr<char> n_char = make_shared<char>(new char[size_]{});

How can I create

char* chr = new char[size_]{}; 

using modern pointers?

like image 230
Person.Junkie Avatar asked Apr 26 '17 10:04

Person.Junkie


2 Answers

shared_ptr n_char = make_shared(new char[size_]{});

make_shared calls new inside, so you never use both. In this case you only call new, because make_shared does not work for arrays.

However, you still need to make it call the right delete:

Before C++17:

You need to specify the deleter explicitly.

std::shared_ptr<char> ptr(new char[size_], std::default_delete<char[]>());

Since C++17:

shared_ptr gains array support similar to what unique_ptr already had from the beginning:

std::shared_ptr<char[]> ptr(new char[size_]);

Be aware that done this simple way you are not tracking length and in multi-threaded environment not synchronizing. If you need the buffer modifiable, making shared pointer to std::string, or struct with std::string and std::mutex in it, will add a level of indirection, but will be otherwise more convenient to use.

like image 180
Jan Hudec Avatar answered Oct 02 '22 13:10

Jan Hudec


You could use std::default_delete specialized for arrays

std::shared_ptr<char> ptr(new char[size_], std::default_delete<char[]>());

See std::default_delete docs. While std::unique_ptr uses default_delete by default when no other deleter is specified and has a partial specialization that handles array types:

std::unique_ptr<char[]> ptr(new char[size_]);

With std::shared_ptr you need to select it manually by passing a deleter to the constructor.

Edit: Thanks to Jan Hudec, c++17 includes a partial specialization for array types as well:

std::shared_ptr<char[]> ptr(new char[size_]);  // c++17
like image 45
unexpectedvalue Avatar answered Oct 02 '22 13:10

unexpectedvalue