简体   繁体   中英

How to convert an array of string pointers into a vector of smart pointers of type string?

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?

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?

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"));
// ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM