Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to store the pointer to the data of a std::string?

Tags:

c++

My question revolves around the mechanics of copy-construction and reallocation.

I have a class, that collects strings. After adding a string to the collection, the string is copied and stored in a vector. But as I also need access to the collection of all the string as const char * const*, I also store the pointers to the data of each string via .c_str().

class MyStrings {
private:
    std::vector<std::string> names;
    std::vector<const char*> cStringPointers;
public:
    const char *const *Data() const
    {
        return this->cStringPointers.data();
    }

    void Add(const std::string &name)
    {
        // copy [name] and store the copy in [this->names].
        this->names.push_back(name); 
        // Store the pointer to the data of the copy.
        this->cStringPointers.push_back(this->names.back().c_str());
    }
}

I am aware, that storing pointers to elements of a vector is bad, because when the vector gets resized, i.e. has to reallocate his memory, those pointers would not be valid anymore.

But I am storing just the pointers to the data. So here is what I think:

If names gets resized, it will move-construct all the strings it contains and so those strings will not allocate new memory, but instead just use the already allocated memory and so my pointers in cStringPointers would still be valid.

My question is now simply: Have I missed something that would make this code unsafe or cause undefined behaviour?

(Assuming that I don't use any exotical architexture and or compiler.)

like image 565
churill Avatar asked Dec 02 '22 09:12

churill


1 Answers

My question is now simply: Have I missed something that would make this code unsafe or cause undefined behaviour?

Yes: you have missed Small String Optimization. It is permitted by the standard and widely implemented, and will lead to dangling pointers as the strings actually move their data to their new location.

like image 120
Quentin Avatar answered Dec 28 '22 23:12

Quentin