How to use unique_ptr and make_unique with const char*

Hi,

I am trying to implement as string class using unique_ptr, but stuck with some issues.

Here is my code :

mystring.h
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace kapil {
  class string final {
    private:
      char* ptr_; //[1]
      size_t sz_;
    public:
      string() noexcept;
      string(const string&);
      string(string&&) noexcept;
      explicit string(const char*); 
      ~string();
  };
} //kapil 


string.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
namespace kapil {

  string::string() noexcept : ptr_{nullptr}, sz_{0} {
  }

  string::string(const string& other) {
    sz_ = strlen(other.ptr_);
    ptr_ = new char[sz_ + 1];
    strcpy(ptr_, other.ptr_);
  }

  string::string(string&& rval) noexcept {
    ptr_ = rval.ptr_;
    sz_ = rval.sz_;
    rval.ptr_ = nullptr;
  }

  string::string(const char* c_string) {  //[2]
    sz_ = strlen(c_string);
    ptr_ = new char[sz_ + 1];
    strcpy(ptr_, c_string);
  }

  string::~string() {
    delete ptr_;
    ptr_ = nullptr;
  }
}


I am trying to write above implementation using unique_ptr, but stuck with how to accomplish definition [2] keeping [1] as unique_ptr.

Like with char* we can do the following:
1
2
3
4
5
  string::string(const char* c_string) {
    sz_ = strlen(c_string);
    ptr_ = new char[sz_ + 1];
    strcpy(ptr_, c_string);
  }


[a]
Is there a way to write something like the following ?
Assuming ptr_ is unique_ptr<char[]>
1
2
3
4
5
  string::string(const char* c_string) {
    sz_ = strlen(c_string);
    ptr_ = make_unique<char[]> (c_string) //or anything similar to achieve behavior of [2]
    strcpy(ptr_, c_string);
  }


[b]
If there is no way to achieve [a], is there any way to avoid new and ensure automatic deletion of memory allocated to ptr_.

[c]
If [a] & [b] are not achievable, then how can I handle cases of memory leaks if the above class has two char* pointer member variables and the constructor throw after allocating memory for one, something like
1
2
3
4
  SomeClass::SomeClass(const char* c_string) {
    ptr1_ = new char[sz_ + 1]; //throws
    ptr2_ = new char[sz_ + 1];
  }


I really appreciate any help in this.
Last edited on
ptr_ = make_shared<char[]> (c_string) //or anything similar to achieve behavior of [2]

make_shared is for making shared pointers. You're looking for make_unique


Something like this, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <memory>
#include <cstring>



namespace kapil {
  class string final {
    private:
      std::unique_ptr<char[]> ptr_;
      size_t sz_;
    public:
      string() noexcept;
      string(const string&);
      string(string&&) noexcept;
      explicit string(const char*); 
      ~string();
      void output() { std::cout << ptr_.get();}
  };
} //kapil 

namespace kapil {

  string::string() noexcept : ptr_{nullptr}, sz_{0} {
  }

  string::string(const string& other) {
    sz_ = other.sz_;
    ptr_ = std::make_unique<char[]>(sz_);
    strcpy(ptr_.get(), other.ptr_.get());
  }

  string::string(string&& rval) noexcept {
    ptr_ = std::move(rval.ptr_);
    sz_ = rval.sz_;
    rval.ptr_ = nullptr;
  }

  string::string(const char* c_string) {  
    sz_ = strlen(c_string) + 1;
    ptr_ = std::make_unique<char[]>(sz_);
    strcpy(ptr_.get(), c_string);
  }

  string::~string() {
  }
}

int main()
{
    kapil::string s("beans");
    kapil::string t(s);
    
    t.output();
}

Last edited on
Thanks Repeater :)
Topic archived. No new replies allowed.