繁体   English   中英

如何使用空终止字符 memset char 数组?

[英]How to memset char array with null terminating character?

用空终止字符 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 );
...
  • 这些中的任何一个比其他的有显着优势吗?
  • 用法 1、2 或 3 会遇到什么样的问题?
  • 处理此请求的最佳方法是什么?

选项一和二是错误的。 第一个使用指针的大小而不是数组的大小,因此它可能不会写入整个数组。 第二个使用sizeof(char*)而不是sizeof(char)所以它会写到数组的末尾。 选项3没问题。 你也可以用这个

memset( buffer, '\0', 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, '\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 与 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}; 在某些情况下。

  • 这些中的任何一个比其他的有显着优势吗?
  • 用法 1、2 或 3 会遇到什么样的问题?

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

第二个和第三个都可以。

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

为什么不只是:

buffer[0] = '\0';

如果这是一个char数组,为什么还要考虑其余的字符呢? 将第一个字节设置为零后,您的buffer中就有了等同于""的内容。

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

如果您绝对必须在 C++ 中使用原始数组(这是一个非常糟糕的主意),请这样做:

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

因为 C++ memset通常是无能者的最后避难所,尽管我在过去几个月内了解到,为了获得可接受的性能,使用当前的工具,当一个人实现自己的字符串类时,有必要降低到那个级别。

使用例如std::string (对于上述情况)、 std::vectorstd::array等,而不是这些看起来需要memset的原始数组等。

从 C++ 11 开始,我会选择:

#include <array>

std::array<char, ARRAY_LENGTH> buffer{ '\0' };

buffer.fill('\0');

Option 3: memset( buffer, '\0', ARRAY_LENGTH ):只会给你数组的长度,但实际上这个参数是内存的总字节数。

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

选项2是对的。

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

memset( buffer, '\0', ARRAY_LENGTH )

ARRAY_LENGTH正是我想填入内存的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM