如何用零终止字符纪机char阵列

How to memset char array with null terminating character?

本文关键字:char 阵列 纪机 字符 何用零 终止      更新时间:2023-10-16

用null终止字符纪念整个字符数组的正确和最安全的方法是什么?我可以列出一些用法:

...
char* buffer = new char [ARRAY_LENGTH];
//Option 1:             memset( buffer, '', sizeof(buffer) );
//Option 2 before edit: memset( buffer, '', sizeof(char*) * ARRAY_LENGTH );
//Option 2 after edit:  memset( buffer, '', sizeof(char) * ARRAY_LENGTH );
//Option 3:             memset( buffer, '', ARRAY_LENGTH );
...
  • 这些中的任何一个比其他(S)具有重要优势?
  • 使用1、2或3的用法可以面对什么样的问题?
  • 处理此请求的最佳方法是什么?

选项一个和第二个完全是错误的。第一个使用指针的大小而不是数组的大小,因此它可能不会写入整个数组。第二种使用sizeof(char*)代替sizeof(char),因此它将在数组的末端写入。选项3还可以。您也可以使用此

memset( buffer, '', sizeof(char)*ARRAY_LENGTH );

,但sizeof(char)保证为1。

愚蠢的方式是价值数组:

char* buffer = new char [ARRAY_LENGTH]();

选项1 仅将第一个sizeof(char*)字节设置为0,或者如果ARRAY_LENGTH < sizeof(char*),则将其置于未定义的行为中。这是由于使用指针的大小而不是类型的大小。

选项2 陷入未定义的行为,因为您正在尝试设置超过array_length字节。sizeof(char*)几乎肯定大于1。

由于这是C (C中没有new),我建议您改用std::string

对于C(假设malloc而不是new[]),您可以使用

memset( buffer, 0, ARRAY_LENGTH );

由于问题不断变化,因此我定义:

1:memset( buffer, '', sizeof(buffer) );

2a: memset( buffer, '', sizeof(char*) * ARRAY_LENGTH );

2b: memset( buffer, '', sizeof(char) * ARRAY_LENGTH );

3:memset( buffer, '', ARRAY_LENGTH );

如果问题仅仅是"呼叫memset的正确方法",而不是"什么是最佳的零方式",那么2B或3是正确的。1和2a是错误的。

您可以在2b vs 3上进行风格战争:是否包括sizeof(char)-有些人因为它是多余的(我通常这样做)而忽略了它相同的代码设置int的数组。也就是说,他们总是将大小乘以许多元素,即使他们知道大小为1。一个可能的结论是,将buffer指向数组指向数组的"最安全"方法是:

std::memset(buffer, 0, sizeof(*buffer) * ARRAY_LENGTH);

如果缓冲区的类型更改(当然,前提是它仍然具有任何类型的ARRAY_LENGTH元素,并且只要All-Bits-Zero仍然是正确的初始值。

,此代码仍然正确。

" 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};有很多话要说。

  • 这些中的任何一个都比其他(S)具有显着优势?
  • 使用1、2或3的用法可以面对什么样的问题?

第一是错误的,因为sizeof(buffer) == sizeof(char*)

第二和第三次都可以。

  • 处理此请求的最佳方法是什么?

为什么不只是:

buffer[0] = '';

如果这是char数组,为什么要打扰其余字符?将第一个字节设置为零,您的buffer中的""等效。

当然,如果您真的坚持要使所有buffer归零,请使用std::fill的答案 - 这是正确的方法。我的意思是std::fill(buffer, buffer + ARRAY_LENGTH, 0);

如果您绝对必须在C 中使用原始数组(这是一个非常好的想法),请这样做:

char* buffer = new char [ARRAY_LENGTH]();

对于C memset通常是无能的最后一个避难所,尽管我在过去几个月内获悉,对于可接受的性能,使用当前工具,当一个人实现自己的字符串类时,有必要达到该水平。

而不是这些原始数组等,似乎需要memset,例如std::string(上述情况),std::vectorstd::array等。

好吧,我个人喜欢选项3:

memset( buffer, '', ARRAY_LENGTH )

ARRAY_LENGTH正是我想填充的内存。

自C 11以来,我应该选择:

#include <array>
std::array<char, ARRAY_LENGTH> buffer{ '' };
buffer.fill('');

Option 3: memset( buffer, '', ARRAY_LENGTH ):只会给您数组的长度,但实际上此参数是总体内存的总字节。

Option 1: memset( buffer, '', sizeof(buffer) ):会给您错误的答案,因为bufferchar*sizeof(buffer)不会给您整个数组的大小,只有指针变量的大小。

选项2是正确的。