#include <cstdlib>
#include <cstring>
#include <string>
using std::string;
string *arr_ptr;
int capacity;
void add() {
int old_capacity = capacity;
capacity <<= 1;
// double the capacity
string *tmp_ptr = new string[capacity];
// apply new space
memmove(tmp_ptr, arr_ptr, sizeof(string) * old_capacity);
// copy
delete[] arr_ptr;
// free the original space
arr_ptr = tmp_ptr;
arr_ptr[capacity - 1] = "occupied";
// without this statement, everything "seems" to be fine.
}
int main() {
arr_ptr = new string[1];
capacity = 1;
for (int i = 0; i < 3; i++) add();
}
Run the code. As you can see, the program crashes when string's desctrutor is invoked. Try to comment the line of delete
and check again.
I suspect that std::string keeps some address information of itself. It won't be informed when its location in memory has changed.
Furthermore, since memmove
doesn't always work as expected, what's the appropriate expression of copying an array of class instance in C++?
memmove
is a lowlevel function for copying bytes. This means that the value of an array of bytes is copied to another array. This is fine for POD data, but not for anything else. The reason is that classes can have a copy constructor, which isn't called by memmove and classes can have extra data like a vpointer for calling virtual member-functions.
The easiest solution for you is to replace memmove
with std::copy
for (#include <algorithm>
) which copies entries instead of bytes:
std::copy(arr_ptr, arr_ptr + old_capacity, tmp_ptr);