0

I have a code like this:

std::string* string_ptr[] = { new std::string("x"), new std::string("y"), new std::string("z") }; 

I need to get a vector like this:

std::vector<std::unique_ptr<string>> vec;

I also need to clear memory in the original string_ptr array and in the new vector.

How to do it better?

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
Yaniboze
  • 63
  • 5
  • 1
    Why do you need an array of pointers (smart or otherwise) where each pointer points at a dynamically allocated `std::string` object? What advantage does that offer you that an array of `std::string` (like `std::string strings[] = {"x", "y", ...}`) or a `std::vector` cannot? – Peter May 27 '20 at 06:51

2 Answers2

2

If u want to transfer the ownership to a vector, you can do as follows (after this u won't have to free any memory. the vector will manage that)

int main() {
    std::string* string_ptr[] = { new std::string("x"), new std::string("y"), new std::string("z") }; // step 1
    size_t sze = size(string_ptr);

    std::vector<std::unique_ptr<std::string>> vec(sze); // step 2
    for(size_t i{}; i < sze; ++i){
        vec[i].reset( string_ptr[i]);
        string_ptr[i] = nullptr;//transfer the elments ownership
    }
}

If you want to copy them only(you will have to manage the memory held by the raw pointers)

int main() {
    std::string* string_ptr[] = { new std::string("x"), new std::string("y"), new std::string("z") }; // step 1
    size_t sze = size(string_ptr);
    std::vector<std::unique_ptr<std::string>> vec(sze); // step 2
    for(size_t i{}; i < sze; ++i){
        ;
        vec[i].reset(new std::string{*string_ptr[i]});
    }
    vec.erase(vec.end()-1);
}

See Why can I not push_back a unique_ptr into a vector?

asmmo
  • 6,409
  • 1
  • 7
  • 22
1

You could write

std::vector<std::unique_ptr<std::string>> vec{&string_ptr[0], &string_ptr[3]};

This transfers the pointers into std::unique_ptr<std::string> objects inside the vector. But keep in mind, you don't need to free the strings in string_ptr since they are now held by the unique pointers inside the vector.

Some further advice: Don't allocate strings in an array and transfer them later to the vector. This isn't exception safe. There will be memory leaks if an exception occurs until the end of the second step. If possible, don't use pointers at all:

std::vector<std::string> vec{ "x", "y", "z" };

or put the string pointers right away into the container:

std::vector<std::unique_ptr<std::string>> vec;
vec.emplace_back(std::make_unique<std::string>("x"));
// ...
phlipsy
  • 2,683
  • 20
  • 32