When you access elements of an array using array[i], I thought that C++ would take the start开发者_运维百科ing position of the array in memory and add i*sizeof(one array element) and then dereference that address (or do something equivalent to what I just described). However, it seems to me that if you have an array of strings (std::string), each element could be a different size based on the number of characters in the string, so there must be something else going on.
Also, to my understanding, array elements are stored in contiguous memory. If you had strings stored in contiguous memory and then appended more characters to one of them, all of the succeeding strings would have to be moved over.
Can someone explain to me how this works?
The string size is constant, but it (at some level) has a pointer to some non-constant-sized data.
The pointer size is constant, the pointee size is not.
std::strings
are objects. The size of one std::string
is the same as the size of another std::string
. They indirectly "contain" their data via dynamic allocation, which does not affect the size of the owning object.
Similarly, if you mean C-style strings, you actually only pass around char*
(or pointers-to-char
). Pointers are always the same size, no matter the length of the block of memory to which they point.
std::string
is a wrapper of char*
, not an array. Arrays can be different sizes, yes, but char*
s are pointers and have a constant size. The char*
that std::string
encapsulates points to dynamically allocated memory. This is why sizeof(std::string)
returns the same size no matter how large the string grows.
If you're refering to the C++ type std::string
, each one of the elements of an array of strings occupy the same ammount of memory. However, each string may contain a pointer pointing to a different position in the memory, of different length, where it actually stores the string.
To see an example (sample code), imagine the std::string
class something like this:
struct string
{
size_t length;
const char* data;
// other members..
};
Note how the structure size is always the same (a size_t
and a pointer), but the memory pointed to, where the actual string is stored, may be different.
The string object has a size and that will differ depending on your implementation complier etc. You are correct in your assessment of who c++ handles arrays, but overlook pointer data. The string class in its bowels has a pointer to some heap data that heap data can be of any arbitrary size, but the pointer to that data is a fixed size. So inside the data layout of a string there is a way for the complier to create uniform objects with non fixed representation data.
Since a string is a character pointer, an array of strings is an array of (char *)
— a contiguous vector of (char *)
pointers. Modifying a string would modify the memory pointed to by each element. Now, if you declared it to be statically allocated:
char foo[10][10];
then in terms of memory layout it's indistinguishable from
char foo2[100];
and it would be possible to corrupt memory by writing past the declared size; this is one reason one should use std::string
instead of C-style strings, which are perhaps the best example of why C is a lousy language for application programming. (An array of std::string
would be an array of objects, each of which would have a (char *)
stored in it somewhere that you wouldn't need to worry about — std::string
does it for you, and much more reliably.)
This is how you would do it in code...
const int ARRSIZE = 5;
string arrayOfStr[ARRSIZE] = {"one", "two", "three"};
for (int i = 0; i < ARRSIZE; ++i)
{
cout << arrayOfStr[i] << endl;
}
精彩评论