使用null终止字符memset整个字符数组的正确和最安全的方法是什么?我可以列出一些用法:
...
char* buffer = new char [ARRAY_LENGTH];
//Option 1: memset( buffer, '\0', sizeof(buffer) );
//Option 2 before edit: memset( buffer, '\0', sizeof(char*) * ARRAY_LENGTH );
//Option 2 after edit: memset( buffer, '\0', sizeof(char) * ARRAY_LENGTH );
//Option 3: memset( buffer, '\0', ARRAY_LENGTH );
...
答案 0 :(得分:20)
选项一和二是错的。第一个使用指针的大小而不是数组的大小,因此它可能不会写入整个数组。第二个使用sizeof(char*)
而不是sizeof(char)
,因此它将写入数组的末尾。选项3没问题。你也可以用这个
memset( buffer, '\0', sizeof(char)*ARRAY_LENGTH );
但sizeof(char)
保证为1。
答案 1 :(得分:13)
惯用的方法是初始化数组:
char* buffer = new char [ARRAY_LENGTH]();
选项1 仅将第一个sizeof(char*)
字节设置为0,或者在ARRAY_LENGHT < sizeof(char*)
时遇到未定义的行为。
选项2 会遇到未定义的行为,因为您尝试设置的字节多于ARRAY_LENGTH个字节。 sizeof(char*)
几乎肯定大于1。
由于这是C ++(C中没有new
),我建议您改用std::string
。
对于C(假设malloc
而不是new[]
),您可以使用
memset( buffer, 0, ARRAY_LENGTH );
答案 2 :(得分:5)
由于问题不断变化,我定义:
1:memset( buffer, '\0', sizeof(buffer) );
2a:memset( buffer, '\0', sizeof(char*) * ARRAY_LENGTH );
2b:memset( buffer, '\0', sizeof(char) * ARRAY_LENGTH );
3:memset( buffer, '\0', ARRAY_LENGTH );
如果问题仅仅是“调用memset
”的正确方法,而不是“将这个数组归零的最佳方法是什么”,则2b或3是正确的。 1和2a是错误的。
你可以进行超过2b vs 3的风格大战:是否要包括sizeof(char)
- 有些人因为冗余(我通常会这样做)而将其排除在外,其他人则将其用于创建一种类型与设置int
数组的相同代码的一致性。也就是说,它们总是将大小乘以一些元素,即使它们知道大小为1.一个可能的结论是,buffer
指向的memset数组的“最安全”方式是:
std::memset(buffer, 0, sizeof(*buffer) * ARRAY_LENGTH);
如果缓冲区的类型发生变化,此代码仍然正确,前提是它继续具有任何类型的ARRAY_LENGTH
个元素,并且假设所有位零都保持正确的初始值。
“C ++不是C”程序员所钟爱的另一个选择是:
/* never mind how buffer is allocated */
std::fill(buffer, buffer + ARRAY_LENGTH, 0);
如果您在意,您可以自己检查一下您的编译器是否将其优化为与优化std::memset
的等效调用相同的代码。
char *buffer = new char [ARRAY_LENGTH]();
在实践中非常好用,但在C ++中几乎没用,因为你几乎从不在第一时间用new
分配一个数组。
std::string buffer(ARRAY_LENGTH, 0);
引入了一种管理缓冲区的特定方式,它可能是您想要的,也可能不是。在某些情况下,char buffer[ARRAY_LENGTH] = {0};
有很多话要说。
答案 3 :(得分:3)
- 这些中的任何一个都有明显的优势吗?
- 使用1,2或3时,我可以面对哪些问题?
1st错了,因为sizeof(buffer) == sizeof(char*)
。
第二和第三是好的。
- 处理此请求的最佳方法是什么?
为什么不呢:
buffer[0] = '\0';
如果这是一个char
数组,为什么要打扰其余的字符呢?将第一个字节设置为零后,您""
中的buffer
就相当于buffer
。
当然,如果你真的坚持让所有std::fill
归零,请使用std::fill(buffer, buffer + ARRAY_LENGTH, 0);
的答案 - 这是正确的方法。我的意思是{{1}}。
答案 4 :(得分:2)
如果你绝对必须在C ++中使用原始数组(这是一个非常不好的想法),那就这样做:
char* buffer = new char [ARRAY_LENGTH]();
对于C ++而言,memset
通常是无能的最后避难所,尽管我在过去几个月内了解到,对于可接受的性能,使用当前的工具,当一个人实现自己的字符串时,有必要降低到那个级别。类。
代替这些看似需要memset
的原始数组等,例如使用std::string
(针对上述情况),std::vector
,std::array
等。
答案 5 :(得分:1)
自C ++ 11起,我应该选择:
#include <array>
std::array<char, ARRAY_LENGTH> buffer{ '\0' };
buffer.fill('\0');
答案 6 :(得分:0)
Option 3: memset( buffer, '\0', ARRAY_LENGTH ):
只会给你数组的长度,但实际上这个参数总共是多少内存字节。
Option 1: memset( buffer, '\0', sizeof(buffer) ):
会给你错误的答案,因为buffer
是char*
。 sizeof(buffer)
不会给出整个数组大小的指针变量大小。
选项2是对的。
答案 7 :(得分:0)
好吧,我个人喜欢选项3:
memset( buffer, '\0', ARRAY_LENGTH )
ARRAY_LENGTH
正是我要填写的内容。