2009-08-25 8 views
10

J'ai un tableau de valeurs arbitraires, donc je l'ai défini comme un tableau de pointeurs void, donc je peux pointer vers n'importe quel type d'information (comme int, tableaux de caractères, etc). Cependant, comment est-ce que je lui assigne un int?Si j'ai un pointeur vide, comment y mettre un int?

Prenez par exemple ces initialisations:

void* data[10]; 
int x = 100; 

Mon intuition pourrait penser, mais cela donne une erreur de compilation:

data[0] = malloc(sizeof(int)); 
*(data[0]) = x; 

Aussi je pensé à utiliser &x, mais je prendrais l'adresse d'une variable locale, qui (à ma compréhension) serait effacée après la sortie de la procédure. Donc, si j'ai une variable locale x, comment l'obtenir dans une variable de type pointeur de variable correctement?

Répondre

24
*((int*)data[0])=x; 

le fera.

Vous pourriez envisager d'utiliser une union. Quelque chose comme ceci:

union myvalues 
{ 
    int i; 
    double d; 
    long l; 
}; 

Vous pourriez alors

union myvalues *foo[10]; 
foo[0] = malloc(sizeof(union myvalues)); 
foo[0]->i = x; 

Vous pouvez également typedef le syndicat. sizeof(union myvalues) sera le maximum de sizeof les membres. Donc, si vous avez int i; et char c[40] dans l'union, sizeof(union myvalues) aura 40. Ecrire à i remplacera alors les 4 premiers caractères dans c (en supposant que vos ints sont 4 octets).

+0

Ou simplement utiliser un tableau de syndicats, et oublier le malloc –

+0

En effet, bon point. J'allais avec le plus proche de l'original. –

+0

Merci, mais cela fonctionnerait avec des pointeurs de tableau de caractères (char *).Et cela ne causerait-il pas de problèmes d'alignement sur certaines plateformes? Et enfin, si j'ai un caractère [40], il me semble que c'est un gaspillage de mémoire de réserver 40 octets si je n'utilise que 4. :-) – pbean

9
*((int *)data[0]) = x; 

Une copie de x sera faite, donc le fait qu'il s'agisse d'une variable locale n'est pas important.

1

pour aliasing des raisons de son mieux pour faire

mempcy(data[0], &x, sizeof(int)); 

Comme il arrive que le compilateur optimise l'appel memcpy comme sizeof (int) est une valeur constante, mais il ne cassera pas différentes règles d'aliasing.

+0

quelles règles d'aliasing? –

+0

Je suppose que Goz s'inquiète du type-punning, mais puisque vous ne pouvez pas déréférencer 'void *', il est toujours sûr AFAIK d'alias avec un pointeur 'void *'. Il ne suffit pas de le déréférencer après avoir lancé autre chose que 'int *' ou 'char *'. –

2

Bien que vous puissiez utiliser une distribution pour effectuer la cession, il est probablement beaucoup plus propre à écrire le code comme:

 
void *data[ 10 ]; 
int x = 100; 
int *p; 

p = malloc(sizeof *p); 
data[ 0 ] = p; 
*p = x; 
+0

Je suis d'accord avec vous pour cet exemple simple, et c'est la méthode que j'ai suivie en premier. Le problème est cependant qu'il y a beaucoup de types de données possibles et différents, donc je devrais déclarer beaucoup de variables locales temporaires qui pourraient ou ne pourraient pas être utilisées à une certaine exécution. – pbean

+0

+1 pour utiliser moins de ponctuation – sigjuice

1

essayez ceci:

data[0] = malloc(sizeof(int)); 
*((int*)data[0]) = x; 

ou

(int) (*(data[0])) = x; 

ne pas oublier de

free (data[0]); 

ensuite.

Questions connexes