Reputation: 1643
I'm reading a book about c++ in an attempt to learn the language.
there is this one example where it creates a vector-like class that only works with strings called stringV
. the class defines a function called reallocate
that should allocate new dynamic memory and moves its strings to the new memory in case the old memory gets full.
void stringV::reallocate(){
size_t newcap = size() ? size() * 2 : 1;
auto newalloc = alloc.allocate(newcap);
auto mem = newalloc;
auto elem = element; // element pointes to the first string object in the memory segment
for (size_t i = 0; i < size(); i++){
alloc.construct(newalloc, std::move(*elem));
newalloc++;
elem++;
}
free(); //destroys and deallocates the dynamic memory held by this object
element = mem;
first_free = newalloc; // one past the last element
cap = element + newcap; // last part of the possibly unconstructed memory
}
this function uses the string class's move constructor witch according to the book, steals the state of the object passed to it by swapping pointers between the string objects(which I assume is a pointer to the first element, similar to a built-in array) instead of copying every char separately.
for example lets assume we have a stringV
object called foo
that has allocated dynamic memory enough for 3 strings. and we start by assigning the strings "one"
, "two"
, and "three"
. now as we try to push a fourth string, "four"
, this container will have to reallocate memory by calling reallocate
However, doesn't the string objects construct their chars in adjacent locations one after the other (similar to the implementation of built-in arrays). and when we use the move constructor were only stealing the pointer to the first char in the string. so won't that mean that the string elements (the chars) "one"
, "two"
, and "three"
are still in the same old, now full, segment of memory. and the new allocated memory would only have to hold the pointers to those elements and any new subsequent strings, "four"
...etc. that get pushed into our foo
object? and won't that have an impact on efficiency (to say the least), considering that our strings(arrays of char) are no longer in adjacent locations?
Upvotes: 1
Views: 132
Reputation: 9617
Literals like "one"
and "two"
are indeed stored in adjacent memory but strings copy them when being created into their buffers (literals are read-only). There is no guarantee on where strings will allocate their buffers; strings don't even allocate their buffers themselves but use allocators.
String's move constructor just passes ownership of the buffer from the old string to the new one, it does not change the location of the buffer in memory so after your reallocate
, all the buffers will be at the same addresses they were before that.
Upvotes: 1