Проблема с std::string*[] C++

Никак не могу понять в чём дело.

   std::string* array_str0 = new std::string[2];
   std::string* array_str1 = new std::string[2];

   array_str0[0] = "00000000";
   array_str0[1] = "111111111111111111111111";

   memmove(array_str1, array_str0, sizeof(std::string) * 2);

   delete[] array_str0;

   for (size_t i = 0; i < 2; i++)
       std::cout << array_str1[i] << "\n";

Вывод:

00000000

0000000════════════════

Если убрать delete[] array_str0, то всё работает правильно:

00000000
111111111111111111111111

С другими типами (int, char) также всё работает правильно. Кто-нибудь может объяснить почему так происходит?


Ответы (1 шт):

Автор решения: Harry

Смотрите - вы просто

memmove(array_str1, array_str0, sizeof(std::string) * 2);

скопировали не содержимое строк, а скопировали их внутреннее представление - те же указатели на выделенную для содержимого строк память.

Удаляя указатель,

delete[] array_str0;

вы вызываете деструкторы строк, которые эту память освобождают. Все. Строк больше нет!

Но в array_str1 лежат указатели на уже удаленные строки, и вы обращаетесь к памяти, которая была освобождена - UB!...

Вот так - через memmove - сложные типы не копируются, только POD (plain old data, грубо - С-шные типы без указателей) - что вы сами заметили: С другими типами (int, char) также всё работает правильно.

Вам надо было копировать примерно так:

array_str1[0] = array_str0[0];
array_str1[1] = array_str0[1];

А у вас получилось взрывоопасная смесь французского (С++) с нижегородским (С)...

→ Ссылка