17

How does a std::vector<std::string> initialize its self when the following code is invoked

std::vector<std::string> original;
std::vector<std::string> newVector = original;

It would seem as if the copy constructor would be invoked on std::vector<std::string> new during newVector = original, but how are the std::string's brought over inside of the orginal? Are they copies or new std::string's? So is the memory in newVector[0] the same as original[0].

The reason I ask is say I do the following

#include <vector>
#include <string>
using namespace std;

vector<string> globalVector;

void Initialize() {
    globalVector.push_back("One");
    globalVector.push_back("Two");
}

void DoStuff() {
    vector<string> t = globalVector;
}

int main(void) {
    Initialize();
    DoStuff();
}

t will fall out of scope of DoStuff (on a non optimized build), but if it t is just filled with pointers to the std::string's in globalVector, might the destructor be called and the memory used in std::string deleted, there for making globalVector[0] filled with garbage std::string's after DoStuff is called?

A nut shell, I am basically asking, when std::vector's copy constructor is called, how are the elements inside copied?

Keith Pinson
  • 7,835
  • 7
  • 61
  • 104
chadb
  • 1,138
  • 3
  • 13
  • 36
  • 4
    Pretty sure this was just an example but in your first code block, `std::vector new = original;`, that `new` is not a legal variable name. I'm sure you know that it's a reserved keyword. – Chris A. Apr 29 '12 at 00:12
  • @ChrisA.: You are right, it was just test code – chadb Apr 29 '12 at 00:41

1 Answers1

26

std::vector and most other standard library containers store elements by value. The elements are copied on insertion or when the container is copied. std::string also maintains its own copy of the data, as far as your usage of it is concerned.

Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • 3
    @BenjaminLindley: You are right, as far as the container's user is concerned. However, as you most likely know, Stroustrup reminds us that some containers, like `std::string`, may copy data *lazily,* meaning that the actual copy action might not internally be done until one of the strings (the original or the copy) is used in a manner that requires it to have been done. At any rate, I think that the answerer is technically right to say *most* in this instance, especially in the manner in which he has qualified his usage. – thb Apr 29 '12 at 00:18
  • 3
    @thb `std::string` is only sort-of a container, it is restricted to "char-like types" (i.e. it cannot store other containers), and copy-on-write is deprecated now that multithreading is prevalent. – Potatoswatter Apr 29 '12 at 00:25
  • @Potatoswatter: I did not know and had not thought of your multithreading point. Of course you are also right about the "sort-of a container." The correction is accepted with thanks. – thb Apr 29 '12 at 00:36
  • 1
    So just to be clear on terminology, `newVector[0] is not the same memory as original[0]` and it the copy constructor is called for the new string? – chadb Apr 29 '12 at 00:43
  • 2
    @chadb: Yes, they are independent containers containing independent elements. That just so happen to have the semantically identical contents. – Nicol Bolas Apr 29 '12 at 00:52