Person.Junkie
Person.Junkie

Reputation: 1886

Using shared_ptr with char*

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?

Upvotes: 10

Views: 31656

Answers (4)

sam
sam

Reputation: 856

In case you want to separate declaration from definition you could use the following:

(tried to demonstrate a simple example with different pointer types and different custom deleters )

   class A
{

public:
    A(const char* const name_)
    {
        size_t len = std::strlen(name_) + 1;


        //Definition
    
        //ptr_name 
        this->ptr_name = 
            std::shared_ptr<char[]>(new char[len], [](char* p)-> void {delete[] p; });
        strcpy_s(this->ptr_name.get(),len,name_);
        //ptr_buffer
        this->ptr_buffer = 
            std::shared_ptr<int[]>(new int[SIZE] {1, 2, 3, 4, 5}, std::default_delete<int[]>());

    }
    void Print()
    {
        std::cout << "Print name " << std::endl;
        std::cout << this->ptr_name << '\n';
        std::cout << "Print buffer " << std::endl;
        for (int i=0; i< SIZE; ++i)
        {
            std::cout << this->ptr_buffer[i] << '\n';
        }
    }
private:
    //Declaration
    std::shared_ptr<char[]> ptr_name;
    std::shared_ptr<int[]> ptr_buffer;
public:
    const static size_t SIZE = 5;

};
void func(A object)
{
    
    object.Print();
}
int main()
{

    const char* str = "Hello World!";
    A a(str);
    func(a);
    a.Print();

    
}

Upvotes: 0

Dimka Ch
Dimka Ch

Reputation: 1

For simple char buffer:

std::shared_ptr<char> ptr( (char*)operator new( buffer_size_here ) );

Upvotes: -3

Jan Hudec
Jan Hudec

Reputation: 76286

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.

Upvotes: 25

unexpectedvalue
unexpectedvalue

Reputation: 6139

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

Upvotes: 5

Related Questions