Можно ли переместить char * в std :: string? - PullRequest
0 голосов
/ 03 июня 2018

Скажем, у меня что-то вроде этого

extern "C" void make_foo (char** tgt) {
  *tgt = (char*) malloc(4*sizeof(char));
  strncpy(*tgt, "foo", 4);
}

int main() {
  char* foo;
  make_foo(&foo);
  std::string foos{{foo}};
  free(foo);
  ...
  return 0;
}

Теперь я хотел бы избежать использования, а затем удалить буфер foo.Т.е. я хотел бы изменить инициализацию foos на что-то вроде

  std::string foos{{std::move(foo)}};

и не использовать явное free.

Оказывается, это на самом деле компилируется и, похоже, работает,но у меня есть довольно подозрительные чувства по этому поводу: действительно ли он перемещает определенную C-строку и правильно освобождает хранилище?Или он просто игнорирует std::move и пропускает хранилище, как только указатель foo выходит из области видимости?

Не то, чтобы я слишком беспокоился о дополнительной копии, но мне интересно, возможно линапишите это в стиле современной семантики движения.

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

tl; dr: Не совсем.

У указателей нет особой семантики перемещения.x = std::move(my_char_ptr) совпадает с x = my_char_ptr.Они не аналогичны, скажем, std::vector, в которых перемещение убирает выделенное пространство.

Однако, в вашем случае, если вы хотите сохранить существующиебуферизует кучу и обрабатывает их как строки - они не могут использовать std::string, так как они не могут быть созданы как обертка существующего буфера (и есть оптимизация с небольшими строками и т. д.).Вместо этого рассмотрите возможность реализации пользовательского контейнера, например, с некоторым буфером строковых данных (std::vector<char>) и std::vector<std::string_view>, элементы которого указывают на этот буфер.

0 голосов
/ 03 июня 2018

std :: string constructor # 5:

Создает строку с инициализированным содержимым с копией строки символов с нулевым символом в конце, на которую указывает s. Длина строки определяется первым нулевым символом.Поведение не определено, если s не указывает на массив из хотя бы Traits :: length (s) +1 элементов CharT, включая случай, когда s является нулевым указателем.

Ваш C-Строка копируется (std::move здесь не имеет значения), и поэтому вам остается только позвонить free на foo.

A std::string никогда не станет владельцем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...