Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do strings in a std::vector<std::string> end up with the same data address?

Tags:

c++

Consider the following C++ program:

#include <iostream>
#include <string>
#include <vector>


int main()
{
    std::vector<std::string> v(2, std::string(24,0));
    for (auto& s : v) {
        std::cout << "Address: " << (void*)s.data() << std::endl;
    }
}

Demo

I would expect each string in the vector to point to a different memory region, but with both gcc 6.3.0 and 8.2.1 when compiling with -D_GLIBCXX_USE_CXX11_ABI=0, they show the same address. (when compiling without the flag, they show different addresses). Why is that?

like image 384
sunmat Avatar asked Aug 29 '19 15:08

sunmat


People also ask

Can vectors store strings?

Use a vector for array-like storage of your strings. Example 4-6 offers a simple example. vector s follow array semantics for random access (they also do a lot more), so they are easy and familiar to use.

What is the difference between std::string and std :: vector?

std::string offers a very different and much expanded interface compared to std::vector<> . While the latter is just a boring old sequence of elements, the former is actually designed to represent a string and therefore offers an assortment of string-related convenience functions.

Is std::string movable?

Yes, std::string (since C++11) is able to be moved i.e. it supports move semantics.

What is the difference between string and vector?

TLDR: string s are optimized to only contain character primitives, vector s can contain primitives or objects. The preeminent difference between vector and string is that vector can correctly contain objects, string works only on primitives.


1 Answers

-D_GLIBCXX_USE_CXX11_ABI=0 (1) with this std::string uses COW strategy which was allowed pre C++11.

Copy On Write is an optimization strategy. With COW when multiple std::strings objects are constructed with the same value only one underlying string array would be created and all objects would point to it. This is what you observe in your code. When writing to one of the objects a copy of the string array unique to that std::string object would be created and then that would be modified.

Since C++11 this strategy is illegal (2) and most implementations now use SSO (Short String Optimization) optimizations for std::string instead.


(1) Understanding GCC 5's _GLIBCXX_USE_CXX11_ABI or the new ABI

(2) Legality of COW std::string implementation in C++11

like image 136
bolov Avatar answered Oct 03 '22 14:10

bolov