2016-09-28 1 views
1

Je dois sécuriser l'espace à l'avance suffisant pour jusqu'à 4k entrées totales réparties entre deux types différents, dans une proportion quelconque, puis le remplir avec des données. J'ai pensé que j'allouerais un espace suffisant pour 4k du type le plus grand, et je déciderais ensuite de le remplir avec des données de quel type il s'agit réellement. Je cours dans un problème où le compilateur me dit erreur (etoa: 1554): type (s) illégal (s): ptr-to-void '+' int.Comment conserver un type de zone de stockage global indépendant de C?

Dans ma fonction init, j'allouent quelque chose de l'espace comme celui-ci:

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 est déclaré à la portée du fichier comme ceci:

static void *ser_dat_ch = NULL; 

Quand je charge les données dans la structure, je voulait faire quelque chose comme

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

, mais c'est ce qui obtient le compi Ler aboyant à moi. Quel est le problème?

+2

Comment "aucune allocation dynamique autorisée" n'est maillée avec 'calloc()'? – EOF

+0

J'utilise 'calloc()' pour toute la zone au tout début (à l'intérieur de ma fonction 'init()') - ce qui est autorisé! – cerr

+0

@cerr, mais 'calloc()' effectue une allocation dynamique. Cela nous laisse incertains de ce que vous entendez par "aucune allocation dynamique autorisée". –

Répondre

6

Dans ce cas particulier, je pense que la solution la plus simple serait de créer un tampon avec 4K entrées d'un type union.

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

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

union AB ser_dat_ch[4000]; 
+0

J'ai complètement oublié les syndicats! Merci! – cerr

+1

Bonne approche, mais gardez à l'esprit que la disposition de la mémoire sera différente (moins compacte), donc la mise en cache pourrait être moins efficace. Ce n'est généralement pas un problème, juste un élément à prendre en compte dans les applications hautes performances. – Thomas

+0

C'est tout aussi compact dans le pire des cas, quand chaque entrée est de type plus grand. – hugomg

3

Vous ne pouvez pas indexer un pointeur vide, car la taille du type d'élément est inconnue. Alors d'abord downcaster votre pointeur sur un type particulier, et alors seulement l'indexation:

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

La raison pour laquelle le compilateur se plaint de l'opérateur + est que ser_dat_ch[lab] est équivalent à *(ser_dat_ch + lab).