2010-08-02 2 views
12

gcc 4.4.4 c89инициализация структурной матрицы с использованием memset

У меня есть следующая структура.

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. Является ли это неправильным способом инициализации массива структуры?

+1

Если вы ввели typedef struct device_sys в dev_sys, вы можете сохранить упомянутый memset. typedef struct device_sys dev_sys; memset (dev_sys, 0, NUM_DEVICES * sizeof (dev_sys)); –

ответ

28

Либо

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 в качестве первого аргумента. Эффект будет таким же. Тем не менее, &dev_sys более уместен в первом варианте, так как если следует идиома memset(ptr-to-object, object-size). Во втором и третьем вариантах более целесообразно использовать dev_sys (или &dev_sys[0]), поскольку это следует за иконой memset(ptr-to-first-element, number-of-elements * element-size).

P.S. Конечно, вместо того, чтобы использовать все, что хак memset фокусов, в вашем конкретном случае, вы должны только объявили ваш массив с инициализатором

struct device_sys dev_sys[NUM_DEVICES] = { 0 }; 

Нет memset необходимости.

+1

ОП сказал c89, разве это не инициализатор c99? – bstpierre

+0

@bstpierre: Нет. Почему?Совокупные инициализаторы были в C с начала времен (ну, почти). – AnT

+0

для вашего первого примера. и dev_sys. Разве это не адрес (адрес). Как адрес фактического указателя. Dev_sys уже находится на указателе. Если я объявил это структурное устройство * dev_sys. Для первого аргумента я бы просто отправил указатель dev_sys. Спасибо – ant2009

8

В коде есть опечатка. Fix:

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

Выбор хороших имен избегает половины ошибок. Я бы рекомендовал «устройства».

+3

возможно даже безопаснее: 'memset (dev_sys, 0, sizeof (dev_sys));' – Drakosha

+0

Это допустимо только в C++. – Lucas

+0

Да, исправлено. –

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)); 
1

Для массива sizeof доставит вам весь размер массива, а не размер отдельного элемента. Оператор sizeof является одним из немногих мест, где массив не рассматривается как указатель на его первый элемент.

Смежные вопросы