C++中char*类型的memset等价函数是什么?

9

我有这段代码

  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);

我知道在C++中使用memcpy和memset是不好的,但我还没有完全理解如何在C++中使用它们,最好不要使用std。

有人知道吗?谢谢。


1
似乎您为名称分配的空间可能少了一个字符。如果您之后要覆盖它,我不太明白为什么要在数组中填充零。 (第一个strcat只需要第一个字符为空,strcpy甚至不需要那个。这两个函数都会自动给字符串加上"\0")哦,而且strlen(name)不会很好地工作,除非该字符串已经包含一个正确结束的C字符串! 它不做任何其他事情,只是计算到第一个空字符的所有字符数。 - UncleBens
7个回答

13

一般情况下,可以使用 std::fill。参考链接:http://www.cplusplus.com/reference/algorithm/fill/

或者在这种特定情况下,您应该考虑使用std::vector<char>

(请注意,在C++中仍然可以使用memset,只需包含#include <cstring>,尽管在C++中不太常用。)


12

当您有一个对象类型的数组时,可以使用std::fill算法作为memset的一种可能替代方法。它适用于迭代器范围和指向数组的指针。

memcpy调用通常可以替换为对std::copy的调用。

例如:

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

memsetmemcpy仍然存在,可以在适当的时候使用。但从许多C++开发者的角度来看,使用裸指针new而不使用资源管理对象是更大的忌讳。最好使用std::stringstd::vector<char>,这样内存释放是自动的,代码也更加安全。


4
"std::fill_n"可能比"fill"更合适。除此之外,回答很好,+1 :) - jalf

2
我知道在C++中使用memcpy和memset是不好的,但我还没有完全明白如何在C++中使用它们,最好不要使用std库。
当使用memcpy和memset合适时,它们并不是禁止使用的。为什么会这样呢?
在C++中有一个std::copy函数,它可以将一组项目(可用于任何类型,而不仅仅是char*)从一个迭代器复制到另一个迭代器。

但是,当它可以被更安全、潜在更高效的std::fill替换时,使用是否合适? - jalf
1
@jalf:毫无疑问,std::fill应该在一般情况下可以使用时优先于memset。我的观点是通常不会完全放弃任何语言功能。一个例子是需要在C和C++中编译的某些代码片段。 - Mehrdad Afshari

2

除了需要手动复制和自己进行内存分配之外,这段C++代码没有任何问题。

然而,我强烈建议在C ++中使用std :: string 来进行字符串操作。


1
如果你只是进行字符串操作,使用 string。

1
要将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)

除此之外,它也适用于非 PODs,并且如果单个元素超过一个字节,您不需要处理字节长度。

然而,如果您只想进行字符串操作,则提供了 std::string 类(对于宽字符字符串,还有 std::wstring)。将它们连接起来就像这样简单:

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

没有什么能阻止你在C++中使用strxxx函数族,但我强烈建议你切换到std::string和STL的其余部分。它也不是完美的,但要少得多容易出错。


-3
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);

我现在明白了,只是想把这段代码粘贴给所有未来的访问者。 注释的行与它们下面的取消注释的行是等效的。C语言是被注释的,C++语言是取消注释的。


那是错误的。注释掉的那一行不等同于 name[0] = '\0'。 - Mauri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接