web-dev-qa-db-ja.com

CまたはC ++で構造体がNULLかどうかを確認する方法

私は次の構造を持っています

typedef struct 
{
   char      data1[10];
   char      data2[10];
   AnotherStruct  stData;
}MyData;

何らかの理由で、実装者はポインタとしてstDataを作成しないことを選択しているため、私はそれで生きなければなりません。私の問題は、stDataメンバーが空であるかどうかをどのように確認するのですか?空の場合、コード内の特定のものをスキップする必要があるためです。

どんな助けも大歓迎です

14
user2101801

AnotherStruct stDataを空にするには何らかの方法が必要です。

  • 最初にAnotherStructに関連するドキュメントとコメントをチェック(またはダブルチェック)し、可能であれば公式の方法があるかどうかを確認してください。

  • おそらくその構造体にはポインターがあり、それがNULLポインターである場合、その構造体は空です。または、0または-1または何かが空であることを意味する整数フィールドがあります。または、空のマークを付けるブール値フィールドもあります。

  • 上記のいずれも存在しない場合は、おそらく、そのようなフィールド、または何らかのフィールドのそのような解釈を追加できます。

  • 上記が失敗した場合、MyDataにブールフィールドを追加して、stDataが空かどうかを確認します。

  • また、空のstDataを意味するdata1および/またはdata2の一部の値(空の文字列?0xFFバイトでいっぱい?)を解釈することもできます。

  • いずれかの構造体の内容を変更または再解釈できない場合は、空のアイテムと空でないアイテムを異なるコンテナ(配列、リストなど)に入れることができます。 MyDataアイテムがヒープから1つずつ割り当てられる場合、これは基本的に フリーリスト を持つことと同じです。

  • 上記のバリエーションでは、空のアイテムと空でないアイテムがすべて1つのコンテナーに混在している場合、pointersまたは空でないアイテム(または空のアイテム、またはあなたのニーズに合うもの)。これには、2つのコンテナーの同期を維持する必要があるという複雑な問題があります。

10
hyde

私はあなたと同じような修正に自分自身を見つけました(did)。特定の構造をパケット化する必要があり、構造内の正確なバイト数を知っていると、構造をシリアル化するのに役立ちます。ただし、一部の構造は空であるため、シリアル化は正確なバイト数の調整に失敗します。

これは3年後ですが、私にとっては次の解決策が見つかりました。

template <typename T> struct is_empty {
    struct _checker: public T { uint8_t dummy; };
    static bool const value = sizeof(_checker) == sizeof(T);
};

結果はis_empty<T>::valueとしてクエリでき、コンパイル時に利用できます。

template <typename S>
typedef union {
    struct __attribute__((__packed__)) {
        ObjId   id;
        S       obj;
    } dataStruct;
    std::array<uint8_t, (sizeof(dataStruct) - is_empty<S>::value)> byteArray;
} _msg_t;

参考文献は次のとおりです。

1
sirajissani

ポインターではない場合、オブジェクトMyDataの作成時に構造体メンバーのメモリが割り当てられます。構造体を定義するとき、callocまたはmemsetを使用してそれらをすべてゼロに設定すると、後で0と比較できます

1
Rajath N R

フラグ変数を見つけることができます。例.

struct AnotherStruct {
    bool valid;
    char aother_data1[10];
    char aother_data1[10];
    //...
};

if (stData.valid==true){
    //do something
}
1
thomas

構造体の定義はサードパーティの機能/ライブラリの一部であり、サードパーティは社内の誰かである可能性が高いと思います。

実装者がstDataをポインターにしないことを選択した場合、理由があります。彼らは、「stData is empty」を表現する方法についてのアイデアを持ちます。ドキュメンテーションでこれらのセマンティクスを検索するか、話してみ​​てください。特定の目的とセマンティクスを持つ構造に独自のセマンティクスを追加しようとしないでください。

そのため、構造体のその部分が空であることを表す事前定義された方法isがある場合は、その方法を使用します。意図した用途で空でない場合は、空にしようとしないでください。簡単に言うと、クラス/構造体を使用するつもりのない方法で使用しないでください。代わりに、「MyData」が意味をなすために必要なデータの一部しか持っていない状況にいる場合は、独自の「MyPartialData」構造体を作成してその状況に対処し、「MyData」に変換します必要なものがすべて揃い、サードパーティのAPIと対話する準備ができたら。

0
Arne Mertz

Intは組み込み型であるため、構造体はユーザー定義型です。

struct x;
int y;

まず、「intが空であるかどうかをどのように判断できますかOR最初に宣言した後ではありません」」

解決策について:-初期化されたOR not:-

struct X
{
  bool b;
  X() : b(false) {}  
};

初期化時にtrueに設定します。

0
ravi