I have the following C++ code:
#include <string>
#include <iostream>
int main(int argc, char** argv)
{
int size;
std::string strArray[3];
std::string str0 = "String 0";
std::string str1 = "String 1";
std::string str2 = "String 2";
strArray[0] = str0;
strArray[1] = str1;
strArray[2] = str2;
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
str1.resize(200, 'a');
for (int i = 0; i < 3; i++)
{
std::cout << strArray[i] << std::endl;
}
std::cout << str1 << std::endl;
std::cin.get();
return 0;
}
The idea here is that I have an array which is a contiguous block of memory, where each member is a std::string, which are mutable and therefore variable in size. I expected this code to break since I resize str1 to take up loads more space than original, and therefore "overflowing" into str2.
Instead I get this output:
String0
String1
String2
String0
String1
String2
String1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
I have two questions about this. First of all, how is it that increasing the size of str1 and adding loads of characters to it does not flow over into str2 even though they should be in a contiguous block of memory?
Second, how come when I print the array for the second time after resizing str1 AND add the characters to it it still prints the original str1? I have a feeling that this will have something to do with the answer to my first question but I can't quite see what is going on here.
std::string class in C++ C++ has in its definition a way to represent a sequence of characters as an object of the class. This class is called std:: string. String class stores the characters as a sequence of bytes with the functionality of allowing access to the single-byte character.
One of the most useful data types supplied in the C++ libraries is the string. A string is a variable that stores a sequence of letters or other characters, such as "Hello" or "May 10th is my birthday!". Just like the other data types, to create a string we first declare it, then we can store a value in it.
string class is part of C++ library that supports a lot much functionality over C style strings. C++ string class internally uses char array to store character but all memory management, allocation, and null termination is handled by string class itself that is why it is easy to use.
The c_str method of std::string returns a raw pointer to the memory buffer owned by the std::string . The pointer is only safe to use while the std::string is still in scope. When the std::string goes out of scope, its destructor is called and the memory is deallocated, so it is no longer safe to use the pointer.
The array of string
objects is contiguous, but the actual string data is stored on the heap*, so the string data itself is not stored contiguously.
* Actually given an implementation that uses the 'small string optimization' the data is contiguous, stored inside the string objects as long as it's small enough to fit. 'String0' is small enough for all the SSO implementations I know of. Once the data grows past what can be stored in-place the implementation moves it onto the heap.
The reason that modifying str1
does not affect the result of printing strArray[1]
is that they are distinct objects with no relation, except that you initialized strArray[1]
with the value of str1
. This is just like doing:
int intArray[3];
int int0 = 0;
int int1 = 1;
int int2 = 2;
intArray[0] = int0;
intArray[1] = int1;
intArray[2] = int2;
int1 = 10000000; // does not modify intArray[1]
The idea here is that the usual behavior for objects in C++ is the same as for 'primitive types' or 'value types' you may be familiar with in other languages. It's possible to implement other behaviors in C++, but std::string
is a regular type.
As barnes53 pointed out, the array of string
only stores the string
object, and can simply hold a pointer to the array of characters that represent the string.
The answer to the second question is that the array assignment is done by value rather than by reference, which implies that a copy of the string is made. That is why modifying the original string as no effect on the array version.
The array is contiguous the strings are not.
You say str1.resize(200, 'a');
which has no effect on the array because the array contains the value
of what str1
used to be not the reference
.
So the array value doesn't get overflowed because the value inside the array never changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With