[英]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 );
...
选项一和二是错误的。 第一个使用指针的大小而不是数组的大小,因此它可能不会写入整个数组。 第二个使用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::vector
、 std::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) ):
会给你错误的答案,因为buffer
是char*
。 sizeof(buffer)
不会给你整个数组的大小,只有指针变量的大小。
选项2是对的。
好吧,我个人喜欢选项 3:
memset( buffer, '\0', ARRAY_LENGTH )
ARRAY_LENGTH
正是我想填入内存的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.