1. ホーム
  2. c++

[解決済み] 構造体をゼロにするためにmemset()または値の初期化?

2023-04-02 17:48:01

質問

Win32 API のプログラミングでは、通常 C struct を使用するのが一般的です。通常、そのうちの2つだけが意味のある値を持ち、他のすべてはゼロにする必要があります。これは2つの方法のどちらかで実現できます。

STRUCT theStruct;
memset( &theStruct, 0, sizeof( STRUCT ) );

または

STRUCT theStruct = {};

2つ目のバリエーションはよりクリーンな印象を与えます。これはワンライナーで、ミスタイプしてエラーを引き起こす可能性のあるパラメータを持ちません。

最初のバリエーションと比較して何か欠点はありますか?どの変種を使うか、そしてその理由は?

どのように解決するのですか?

この2つのコンストラクトは は非常に はその意味において異なっています。最初のものは memset 関数で、これは メモリのバッファを特定の値に設定する . 2番目の オブジェクトを初期化する . ちょっとしたコードで説明しましょう。

構造体があるとします。 POD型のみ ("Plain Old Data" - を参照してください。 C++のPOD型とは何ですか? )

struct POD_OnlyStruct
{
    int a;
    char b;
};

POD_OnlyStruct t = {};  // OK

POD_OnlyStruct t;
memset(&t, 0, sizeof t);  // OK as well

この場合 POD_OnlyStruct t = {} または POD_OnlyStruct t; memset(&t, 0, sizeof t) の違いだけなので、大きな違いはありません。 アライメント の場合、バイトがゼロに設定されることです。 memset が使用されます。通常、これらのバイトにアクセスすることはないため、あなたにとって違いはありません。

一方、質問にC++とタグ付けされているので、別の例を試してみましょう。 型が POD と異なる :

struct TestStruct
{
    int a;
    std::string b;
};

TestStruct t = {};  // OK

{
    TestStruct t1;
    memset(&t1, 0, sizeof t1);  // ruins member 'b' of our struct
}  // Application crashes here

この場合、以下のような式を使用します。 TestStruct t = {} がよくて memset を使うとクラッシュします。以下は、もし memset - 型のオブジェクトを TestStruct のオブジェクトが作成され、その結果、型 std::string 型のオブジェクトが作成されます。次に memset はオブジェクトが存在するメモリを設定します。 b が置かれていたメモリを特定の値、例えばゼロに設定します。さて、TestStructオブジェクトがスコープの外に出ると、それは破壊されることになります。そして、そのメンバーである std::string b のメンバーである が破壊されると、そのオブジェクトのすべての内部構造が によって破壊されたため、クラッシュが発生します。 memset .

というわけで、現実は これらのことは非常に異なっています。 であり、時には memset をゼロにする必要がある場合もありますが、常に自分が何をしているかを理解し、2番目の例のような間違いを犯さないようにすることが重要です。

私の投票 - 使用する memset を使う。 のみ が必要な場合は デフォルト 初期化 x = {} を、それ以外の場合は