15

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?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
sunmat
  • 6,976
  • 3
  • 28
  • 44

1 Answers1

15

-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

bolov
  • 72,283
  • 15
  • 145
  • 224