2016-09-28 1 views
1

Мне нужно заранее зарезервировать пространство для размещения до 4 тыс. Записей, разделенных на два разных типа, в любой пропорции, а затем заполнять их данными. Я думал, что я выделил бы пространство, достаточное для 4k более крупного типа, а затем решите заполнить его данными, какие они есть на самом деле. Я столкнулся с проблемой, когда компилятор сообщает мне error (etoa: 1554): незаконный тип (ы): ptr-to-void '+' int.Как сохранить тип хранилища глобальной памяти в C?

В моей функции инициализации, я выделяю пространство что-то вроде этого:

ser_dat_ch = calloc(LABEL_T_CNT, 
     (sizeof(mpls_vpws_t) > sizeof(mpls_vpls_t) 
     ? sizeof(mpls_vpws_t) 
     : sizeof(mpls_vpls_t))); 

где ser_dat_ch объявлен в области видимости файла, как так:

static void *ser_dat_ch = NULL; 

Когда я загрузить данные в структуру, я хотел сделать что-то вроде

rv = switch_mpls_vpws_data_get(lab, (mpls_vpws_t*)&ser_dat_ch[lab]); 

, но это то, что получает compi я лаяла на меня. В чем проблема?

+2

Как не допускается использование динамических распределений с помощью 'calloc()'? – EOF

+0

Я использую 'calloc()' для всей области в самом начале (внутри моей функции 'init()') - что разрешено! – cerr

+0

@cerr, но 'calloc()' выполняет динамическое распределение. Это оставляет нам неуверенность в том, что вы подразумеваете под «невозможными динамическими распределениями». –

ответ

6

В этом конкретном случае я считаю, что самым простым решением было бы создать буфер с 4K элементами типа объединения.

struct A {/**/}; 
struct B {/**/}; 

union AB { 
    struct A a; 
    struct B b; 
}; 

union AB ser_dat_ch[4000]; 
+0

Я полностью забыл о союзах! Благодаря! – cerr

+1

Отличный подход, но имейте в виду, что макет памяти будет отличаться (менее компактный), поэтому кэширование может быть менее эффективным. Обычно это не проблема, а только то, что нужно знать в высокопроизводительных приложениях. – Thomas

+0

Его так же компактно в худшем случае, хотя каждая запись имеет больший тип. – hugomg

3

Вы не можете проиндексировать указатель на пустоту, так как размер типа элемента неизвестен. Таким образом, первое обратное приведение указателя к определенному типу, и только после этого делать индексацию:

rv = switch_mpls_vpws_data_get(lab, &((mpls_vpws_t*)ser_dat_ch)[lab]); 

Причиной компилятор жалуется на операторе + является то, что ser_dat_ch[lab] эквивалентно *(ser_dat_ch + lab).

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