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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:47:30  来源:igfitidea点击:

How to memset char array with null terminating character?

c++arraysc++11memsetnull-terminated

提问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 newin C), I suggest you use a std::stringinstead.

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

For C (assuming mallocinstead 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 bufferis:

您可以在 2b 与 3 之间进行风格War:是否包括sizeof(char)或不包括- 有些人因为它是多余的(我通常这样做)而将其排除在外(我通常这样做),其他人则将其放入以创建一种具有相同代码设置的一致性的数组int。也就是说,即使他们知道大小为 1,他们也总是将大小乘以多个元素。 一个可能的结论是,对指向的数组进行 m​​emset 的“最安全”方法buffer是:

##代码##

This code remains correct if the type of buffer changes, provided of course that it continues to have ARRAY_LENGTHelements 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 newin 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 chararray, 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 bufferzeroed, 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++ memsetis 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::arrayetc.

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

回答by Amit G.

Since C++ 11, I whould choose:

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

##代码##

回答by Simon Lau

Well, personally I like option 3:

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

##代码##

ARRAY_LENGTHis 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, bufferis char*. sizeof(buffer)would not give you size of whole array only size of a pointer variable.

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

Option 2 is right.

选项2是对的。