When you declare a C++ array, it constructs all of the objects on the stack, and they stay there until the array itself is deleted:
std::string ArrayOfStrings[10]; //There are now ten strings here
Objects can't be "removed" from this kind of array. When ArrayOfStrings goes out of scope, it automatically deletes all the strings in the array. If you edit an object in this array, that object itself is changed. You actually changed the string itself, not some pointer or reference.
If you have an array of pointers, then C++ constructs all of the pointers, but you have to manage what they point at yourself:
std::string* ArrayOfPointersToStrings[10];
You can manually delete strings that the pointers in the array point to, but you have to do all of that yourself. When ArrayOfPointersToStrings goes out of scope, it WILL NOT delete anything the strings point at. If you edit a pointer without deleting it first, that's a memory leak, and that's bad.
If you have a std::vector, C++ constructs only some objects depending on how you construct it:
std::vector<std::string> VectorOfStrings(10);
This creates a dynamic array of strings. It is possible to remove objects from a vector, in which case the vector instantly deletes it and rearranges the rest for you. If you edit an object in this array, that object itself is changed. You actually changed the string itself, not some pointer or reference.
To clarify comments:
char *myLiteral = "APPLE";
//"APPLE" is an immutable string, myLiteral points at it.
std::string s= myLiteral;
std::string t = myLiteral;
//s and t each makes a _seperate_ _mutable_ copy of "APPLE"
s[3] = '?';
//s is now "APP?E", because we just changed the L. NO COPY WAS DONE.
std::cout << t[3];
//displays "L", because t's copy was never changed.