C++ 如何使用空终止字符来设置字符数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12935752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to memset char array with null terminating character?
提问by Koray
What is the correct and safest way to memset the whole character array with the null terminating character? I can list a few usages:
使用空终止字符 memset 整个字符数组的正确和最安全的方法是什么?我可以列出一些用法:
...
char* buffer = new char [ARRAY_LENGTH];
//Option 1: memset( buffer, 'memset( buffer, 'char* buffer = new char [ARRAY_LENGTH]();
', sizeof(char)*ARRAY_LENGTH );
', sizeof(buffer) );
//Option 2 before edit: memset( buffer, 'memset( buffer, 0, ARRAY_LENGTH );
', sizeof(char*) * ARRAY_LENGTH );
//Option 2 after edit: memset( buffer, 'std::memset(buffer, 0, sizeof(*buffer) * ARRAY_LENGTH);
', sizeof(char) * ARRAY_LENGTH );
//Option 3: memset( buffer, '/* never mind how buffer is allocated */
std::fill(buffer, buffer + ARRAY_LENGTH, 0);
', ARRAY_LENGTH );
...
- Does any of these have significant advantage over other(s)?
- What kind of issues can I face with with usages 1, 2 or 3?
- What is the best way to handle this request?
- 这些中的任何一个是否比其他人有明显的优势?
- 使用用法 1、2 或 3 时我会遇到什么样的问题?
- 处理此请求的最佳方法是什么?
回答by Dirk Holsopple
Options one and two are just wrong. The first one uses the size of a pointer instead of the size of the array, so it probably won't write to the whole array. The second uses sizeof(char*)
instead of sizeof(char)
so it will write past the end of the array. Option 3 is okay. You could also use this
选项一和二是错误的。第一个使用指针的大小而不是数组的大小,因此它可能不会写入整个数组。第二个使用sizeof(char*)
而不是sizeof(char)
所以它将写入数组的末尾。选项 3 没问题。你也可以用这个
buffer[0] = 'char* buffer = new char [ARRAY_LENGTH]();
';
but sizeof(char)
is guaranteed to be 1.
但sizeof(char)
保证为1。
回答by Luchian Grigore
The idiomatic way is value-initializing the array:
惯用的方法是对数组进行值初始化:
#include <array>
std::array<char, ARRAY_LENGTH> buffer{ 'memset( buffer, '##代码##', ARRAY_LENGTH )
' };
buffer.fill('##代码##');
Option 1only sets the first sizeof(char*)
bytes to 0, or runs into undefined behavior if ARRAY_LENGHT < sizeof(char*)
.
选项 1仅将第一个sizeof(char*)
字节设置为 0,如果ARRAY_LENGHT < sizeof(char*)
.
Option 2runs into undefined behavior because you're attempting to set more than ARRAY_LENGTH bytes. sizeof(char*)
is almost certainly greater than 1.
选项 2遇到未定义的行为,因为您尝试设置的字节数超过 ARRAY_LENGTH 字节。 sizeof(char*)
几乎肯定大于 1。
Since this is C++ though (no new
in C), I suggest you use a std::string
instead.
由于这是 C++(new
在 C 中没有),我建议您改用 a std::string
。
For C (assuming malloc
instead of new[]
), you can use
对于 C(假设malloc
而不是new[]
),您可以使用
回答by Steve Jessop
Since the question keeps changing, I define:
由于问题不断变化,我定义:
1: memset( buffer, '\0', sizeof(buffer) );
1: memset( buffer, '\0', sizeof(buffer) );
2a: memset( buffer, '\0', sizeof(char*) * ARRAY_LENGTH );
2a: memset( buffer, '\0', sizeof(char*) * ARRAY_LENGTH );
2b: memset( buffer, '\0', sizeof(char) * ARRAY_LENGTH );
2b: memset( buffer, '\0', sizeof(char) * ARRAY_LENGTH );
3: memset( buffer, '\0', ARRAY_LENGTH );
3: memset( buffer, '\0', ARRAY_LENGTH );
If the question is merely, "what is the correct way to call memset
" rather than "what is the best way to zero this array", then either 2b or 3 is correct. 1 and 2a are wrong.
如果问题仅仅是“调用的正确方法是什么memset
”而不是“将此数组归零的最佳方法是什么”,那么 2b 或 3 都是正确的。1 和 2a 是错误的。
You can have a style war over 2b vs 3: whether to include the sizeof(char)
or not -- some people leave it out because it's redundant (I usually do), other people put it in to create a kind of consistency with the same code setting an array of int
. That is to say they always multiply a size by a number of elements, even though they know the size is 1. One possible conclusion is that the "safest" way to memset the array pointed to by buffer
is:
您可以在 2b 与 3 之间进行风格War:是否包括sizeof(char)
或不包括- 有些人因为它是多余的(我通常这样做)而将其排除在外(我通常这样做),其他人则将其放入以创建一种具有相同代码设置的一致性的数组int
。也就是说,即使他们知道大小为 1,他们也总是将大小乘以多个元素。 一个可能的结论是,对指向的数组进行 memset 的“最安全”方法buffer
是:
This code remains correct if the type of buffer changes, provided of course that it continues to have ARRAY_LENGTH
elements of whatever type that is, and provided that all-bits-zero remains the correct initial value.
如果缓冲区的类型发生变化,则此代码保持正确,当然前提是它继续具有ARRAY_LENGTH
任何类型的元素,并且所有位为零保持正确的初始值。
Another option beloved of "C++ is not C" programmers, is:
“C++ 不是 C”程序员钟爱的另一个选项是:
##代码##If you care, you can then check for yourself whether or not your compiler optimizes this to the same code to which it optimizes the equivalent call to std::memset
.
如果您关心,您可以自己检查您的编译器是否将其优化为与优化对std::memset
.
char *buffer = new char [ARRAY_LENGTH]();
is nifty but almost useless in C++ in practice because you pretty much never allocate an array with new
in the first place.
char *buffer = new char [ARRAY_LENGTH]();
在 C++ 中很漂亮但在实践中几乎没用,因为你几乎从不首先分配数组new
。
std::string buffer(ARRAY_LENGTH, 0);
introduces a particular way of managing the buffer, which may or may not be what you want but often is. There's a lot to be said for char buffer[ARRAY_LENGTH] = {0};
in some cases.
std::string buffer(ARRAY_LENGTH, 0);
介绍了一种管理缓冲区的特殊方式,这可能是您想要的,也可能不是您想要的,但通常是。有很多关于可说char buffer[ARRAY_LENGTH] = {0};
在某些情况下。
回答by PiotrNycz
- Does any of these have significant advantage over other(s)?
- What kind of issues can I face with with usages 1, 2 or 3?
- 这些中的任何一个是否比其他人有明显的优势?
- 使用用法 1、2 或 3 时我会遇到什么样的问题?
1st is wrong, because sizeof(buffer) == sizeof(char*)
.
第一个是错误的,因为sizeof(buffer) == sizeof(char*)
。
2nd and 3rd are OK.
2号和3号没问题。
- What is the best way to handle this request?
- 处理此请求的最佳方法是什么?
Why not just:
为什么不只是:
##代码##If this is a char
array, why bother with the rest of the characters? With the first byte set to zero, you have the equivalent of ""
in your buffer
.
如果这是一个char
数组,为什么还要麻烦其余的字符呢?将第一个字节设置为零,您""
在buffer
.
Of course, if you really insist on having all of buffer
zeroed, use the answer with std::fill
- this is the proper way. I mean std::fill(buffer, buffer + ARRAY_LENGTH, 0);
.
当然,如果您真的坚持将所有buffer
归零,请使用答案与std::fill
- 这是正确的方法。我的意思是std::fill(buffer, buffer + ARRAY_LENGTH, 0);
。
回答by Cheers and hth. - Alf
If you absolutely must use a raw array in C++ (it's a very ungood idea), do it like this:
如果您绝对必须在 C++ 中使用原始数组(这是一个非常糟糕的主意),请这样做:
##代码##For C++ memset
is generally the last refuge of the incompetent, although I learned within the last few months that for acceptable performance, with current tools, it's necessary to go down to that level when one implements one's own string class.
因为 C++memset
通常是无能者的最后避难所,尽管我在最近几个月内了解到,为了获得可接受的性能,使用当前工具,当实现自己的字符串类时,有必要降到该级别。
Instead of these raw arrays etc., which can appear to need memset
, use e.g. std::string
(for the above case), std::vector
, std::array
etc.
而不是这些看起来需要的原始数组等,memset
使用例如std::string
(对于上述情况)std::vector
,std::array
等。
回答by Amit G.
Since C++ 11, I whould choose:
从 C++ 11 开始,我会选择:
##代码##回答by Simon Lau
Well, personally I like option 3:
好吧,我个人喜欢选项 3:
##代码##ARRAY_LENGTH
is exactly what I would like to fill in the memory.
ARRAY_LENGTH
正是我想填满的记忆。
回答by taufique
Option 3: memset( buffer, '\0', ARRAY_LENGTH ):
will give you only length of array but actually this parameter is total how much byte of memory.
Option 3: memset( buffer, '\0', ARRAY_LENGTH ):
只会给你数组的长度,但实际上这个参数是总共多少字节的内存。
Option 1: memset( buffer, '\0', sizeof(buffer) ):
will give you wrong answer because, buffer
is char*
. sizeof(buffer)
would not give you size of whole array only size of a pointer variable.
Option 1: memset( buffer, '\0', sizeof(buffer) ):
会给你错误的答案,因为buffer
是char*
。sizeof(buffer)
不会给你整个数组的大小,只有指针变量的大小。
Option 2 is right.
选项2是对的。