23

gcc 4.4.4 c89

私は次のような構造をしています。

struct device_sys
{
    char device[STRING_SIZE];
    int id;
    char category;
};

int main(void)
{
    struct device_sys dev_sys[NUM_DEVICES];

    memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(dev_sys));

    return 0; 
}

memsetを呼び出すと、スタックダンプが発生します。これは、構造体配列を初期化する正しい方法ではありませんか?

4

4 に答える 4

46

また

memset(&dev_sys, 0, sizeof dev_sys);

また

memset(dev_sys, 0, NUM_DEVICES * sizeof(struct device_sys));

または、必要に応じて

memset(dev_sys, 0, NUM_DEVICES * sizeof *dev_sys);

ただし、元のバリアントにあるものではありません。

すべてのバリアントの特定のケースでは、最初の引数としてまたは のいずれ&dev_sysかを使用できることに注意してください。dev_sys効果は同じになります。ただし、 if はイディオム&dev_sysに従うため、最初のバリアントの方が適切です。memset(ptr-to-object, object-size)2 番目と 3 番目のバリアントでは、dev_sys(または&dev_sys[0])を使用する方が適切memset(ptr-to-first-element, number-of-elements * element-size)です。

PSもちろん、ハック的なトリックをすべて使用する代わりにmemset、特定のケースでは、初期化子を使用して配列を宣言する必要があります

struct device_sys dev_sys[NUM_DEVICES] = { 0 };

必要ありませんmemset

于 2010-08-02T16:12:56.987 に答える
11

コードにタイプミスがあります。修理:

memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(struct device_sys));

適切な名前を選択すると、バグの半分を回避できます。私は「デバイス」をお勧めします。

于 2010-08-02T16:03:07.847 に答える
1

sizeof変数ではなく型を演算子に渡す必要があります。

memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(struct device_sys));

私は構造体に使用することを好みますtypedef

typedef struct tag_device_sys
{
    char device[STRING_SIZE];
    int id;
    char category;
} device_sys;

memset次のように使用できます。

    memset(dev_sys, 0, (size_t)NUM_DEVICES * sizeof(device_sys));
于 2010-08-02T16:12:54.680 に答える
1

配列のsizeof場合、個々の要素のサイズではなく、配列全体のサイズを取得します。sizeof演算子は、配列が最初の要素へのポインターとして扱われない数少ない場所の 1 つです。

于 2010-08-02T17:11:33.087 に答える