C ++ эквивалент для memset на char * - PullRequest
7 голосов
/ 25 января 2010

У меня есть этот код

  char * oldname = new char[strlen(name) + 1];

  memcpy(oldname,name,strlen(name) + 1);

  name = new char[strlen(oldname) + strlen(r.name) + 1];
  memset(name, '\0', strlen(name));

  strcat(name,oldname);
  strcat(name," ");
  strcat(name,r.name);

Я понимаю, что нет необходимости использовать memcpy и memset, но я не совсем понял, как использовать это в C ++, желательно без std.

Кто-нибудь знает?Спасибо.

Ответы [ 7 ]

10 голосов
/ 25 января 2010

В общем, есть std::fill. http://www.cplusplus.com/reference/algorithm/fill/

Или, в данном конкретном случае, вы должны рассмотреть возможность использования std::vector<char>.

(Обратите внимание, что memset все еще может использоваться в C ++, если вы используете #include <cstring>, хотя в C ++ это менее идиоматично.)

9 голосов
/ 25 января 2010

Одной из возможных замен memset, когда у вас есть массив типов объектов, является использование алгоритма std::fill. Работает с диапазонами итераторов, а также с указателями на массивы.

memcpy звонки обычно можно заменить звонками на std::copy.

, например

std::copy(name, name + strlen(name) + 1, oldname);
// ...
std::fill(name, name + strlen(name), '\0');

memset и memcpy все еще там и могут использоваться при необходимости. С точки зрения многих разработчиков C ++, вероятно, нет ничего более важного в том, чтобы использовать raw new и не использовать объект управления ресурсами. Гораздо лучше использовать std::string или std::vector<char>, чтобы освобождение памяти выполнялось автоматически, а код был более безопасным для исключений.

2 голосов
/ 25 января 2010

Кроме неудобства, связанного с необходимостью вручную копировать и выполнять все выделение памяти самостоятельно, в этом коде C ++ нет ничего плохого.

Однако я настоятельно рекомендую использовать std::string для работы со строками в C ++.

2 голосов
/ 25 января 2010

Я понимаю, что нет необходимости использовать memcpy и memset, но я точно не понял, как использовать это в C ++, желательно без std.

Это не нет-нет, использовать memcpy и memset, когда их использование уместно. Почему это должно быть?

В C ++ есть std::copy, который копирует набор элементов (работает с любым типом, а не только с char*) из итератора в другой.

1 голос
/ 25 января 2010

Чтобы скопировать из a в b, возьмите std::copy(src_start,src_end,dest_start), который увеличивает src_start, и копируйте его в следующий элемент назначения, пока не будет встречено src_start==src_end.

memcpy(oldname,name,strlen(name)+1)
// is the same as
std::copy(name,name+strlen(name)+1,oldname)

.. за исключением того, что он также будет работать для не POD, и вам не нужно возиться с длиной в байтах, если один элемент больше одного байта.

Однако, если вы просто хотите манипулировать строками, предоставляется класс std::stringstd::wstring для широких строковых символов). Объединить их так же просто, как:

std::string s = "name",s2 = ..,s3 = ..;
s = s2+s+s3+"Hello";

Ничто не мешает вам использовать семейство функций strxxx в C ++, но я настоятельно рекомендую вам переключиться на std::string и остальные STL. Он также не идеален, но гораздо менее подвержен ошибкам.

1 голос
/ 25 января 2010

Если вы просто манипулируете строкой, используйте строку.

0 голосов
/ 25 января 2010
char * oldname = new char[strlen(name) + 1];

    //memcpy(oldname,name,strlen(name) + 1);
    strcpy(oldname,name);

    name = new char[strlen(oldname) + strlen(r.name) + 1];
    //memset(name, '\0', strlen(name));
    name[0] = '\0';

    strcat(name,oldname);
    strcat(name," ");
    strcat(name,r.name);

Я понимаю это сейчас, просто хотел вставить этот код для всех будущих посетителей Закомментированные строки эквивалентны некомментированным под ними. С комментируется, С ++ не комментируется.

...