16

null 終端文字を使用して文字配列全体を 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 では、どのような問題が発生する可能性がありますか?
  • この要求を処理する最善の方法は何ですか?
4

8 に答える 8

13

慣用的な方法は、配列を値で初期化することです。

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

オプション 1は、最初のsizeof(char*)バイトのみを 0 に設定するか、未定義の動作を実行しますARRAY_LENGTH < sizeof(char*)。これは、型のサイズではなくポインターのサイズを使用しているためです。

オプション 2 では、ARRAY_LENGTH バイトを超える値を設定しようとしているため、未定義の動作が発生します。 sizeof(char*)ほぼ確実に 1 より大きい。

ただし、これは C++ であるため (C にはありませんnew)、代わりに a を使用することをお勧めしますstd::string

mallocCの場合(の代わりに仮定new[])、使用できます

memset( buffer, 0, ARRAY_LENGTH );
于 2012-10-17T13:44:38.207 に答える
6

質問は変わり続けるので、私は次のように定義します。

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であることを知っていても、常にサイズに要素数を掛けます。考えられる結論の1つは、が指す配列をmemsetする「最も安全な」方法bufferは次のとおりです。

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

このコードは、バッファのタイプが変更されても、もちろん、それがARRAY_LENGTHどのようなタイプの要素でもあり続け、すべてのビットがゼロであり、正しい初期値のままである限り、正しいままです。

「C++ は C ではない」プログラマーに好まれるもう 1 つのオプションは、次のとおりです。

/* never mind how buffer is allocated */
std::fill(buffer, buffer + ARRAY_LENGTH, 0);

気にする場合は、コンパイラが への同等の呼び出しを最適化するのと同じコードにこれを最適化するかどうかを自分で確認できますstd::memset

char *buffer = new char [ARRAY_LENGTH]();newは気の利いたものですが、そもそも配列を割り当てることはほとんどないため、実際には C++ ではほとんど役に立ちません。

std::string buffer(ARRAY_LENGTH, 0);バッファを管理する特定の方法を紹介します。これは、必要な場合とそうでない場合がありますが、多くの場合はそうです。char buffer[ARRAY_LENGTH] = {0};場合によっては、言いたいことがたくさんあります。

于 2012-10-17T14:01:12.560 に答える
4
  • これらのうち、他のものよりも大きな利点があるものはありますか?
  • 使用方法 1、2、または 3 では、どのような問題が発生する可能性がありますか?

1st は間違っていsizeof(buffer) == sizeof(char*)ます。

2枚目、3枚目はOKです。

  • この要求を処理する最善の方法は何ですか?

それだけではない理由:

buffer[0] = '\0';

これがchar配列である場合、残りの文字を気にする必要はありません。最初のバイトをゼロに設定すると""buffer.

もちろん、すべてをbufferゼロにすることを本当に主張する場合は、答えを使用してstd::fillください-これが適切な方法です。つまりstd::fill(buffer, buffer + ARRAY_LENGTH, 0);

于 2012-10-17T14:09:42.903 に答える
2

C++ で絶対に生の配列を使用する必要がある場合 (これは非常に悪い考えです)、次のようにします。

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

一般的に、 C++memsetは無能な人の最後の避難所ですが、現在のツールで許容できるパフォーマンスを得るには、独自の文字列クラスを実装するときにそのレベルまで下げる必要があることをここ数か月で学びました。

が必要と思われるこれらの生の配列などの代わりに、(上記の場合)などをmemset使用します。std::stringstd::vectorstd::array

于 2012-10-17T13:47:06.090 に答える