12
votes

Si j'ai un pointeur vide, comment puis-je y mettre un INT?

J'ai une gamme de valeurs arbitraires, je l'ai donc définie comme une matrice de pointeurs de vide, je peux donc indiquer n'importe quel type d'informations (comme int , tableaux de caractères, etc.). Cependant, comment attribuez-moi effectivement un int à celui-ci?

prendre par exemple ces initialisations: xxx

mon intuition penserait que cela, mais Cela donne une erreur de compilation: xxx

J'ai également pensé à utiliser & x , mais je prendrais l'adresse d'une variable locale, qui (à mon compréhension) serait effacé après avoir quitté la procédure. Donc, si j'ai une variable locale x , comment puis-je l'obtenir dans un type de pointeur vide de variable correctement?


0 commentaires

5 Réponses :


11
votes
*((int *)data[0]) = x;
A copy of x will be made, so the fact it is a local variable is not important.

0 commentaires

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

5 commentaires

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


Merci mais cela fonctionnerait-il avec des pointeurs de réseau de caractères également (Char *). Et cela ne causerait-il pas de problèmes d'alignement sur certaines plates-formes? Et enfin, si j'ai un char [40], il semble un gaspillage de mémoire de réserver 40 octets si je ne vais que utiliser 4. :-)


Si je comprends bien, les syndicats sont alignés sur une limite adaptée à leur plus grand membre, donc aucun problème d'alignement. Char [40]: Bien sûr. C'était juste un exemple pratique pour expliquer la taille. Vous pouvez inclure un caractère * dans l'Union. Cela pourrait se retrouver avec deux allocations (allouant l'union, puis la mémoire tampon pointée par le char *). Il y aurait deux façons d'éviter que: a) Comme Neil suggère ci-dessus, il suffit d'avoir un éventail de syndicats au lieu d'une gamme de pointeurs aux syndicats b) faire quelque chose comme FOO [0] = malloc (taille de myvalues) + longueur_of_str + 1); foo [0] -> c = ((char *) foo [0]) + Taille de (Union Myvalues);


Pourquoi avez-vous besoin de la déférence? L'opérateur [] ne fait-il pas cela? (comme si vous avez IN * N; vous venez de faire n [0] = 23; pas * (n [0]) = 23;)


@Jonathan. Le questionneur avait une annulation * données [10]; - C'est-à-dire un éventail de vide s. Les données [0] sont donc un vide et ont besoin de la déséroférance. Iow, votre exemple serait INT ** N, et vous faites n [0] [0] = 23; ou * (n [0]) = 23;



3
votes

Pour des raisons d'aliasing, c'est bien mieux de faire xxx

car il se produit, le compilateur optimisera l'appel MEMCY comme Tailleof (int) est une valeur constante, mais elle ne brisera pas divers aliasings règles.


1 commentaires

J'assume Goz s'inquiète de la punning de type, mais puisque vous ne pouvez pas la désarférence vide * , il est toujours en sécurité Afaik à alias avec un point de signature . Il suffit de ne pas la désarférement après avoir été jetée à autre chose que int * ou char * .



2
votes

Bien que vous puissiez utiliser une distribution pour faire la mission, il est probablement beaucoup plus propre d'écrire le code comme:

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

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


1 commentaires

Je suis d'accord avec vous pour cet exemple simple, et c'était la méthode que je suis allé pour la première fois. Le problème est cependant qu'il existe de nombreux types de données possibles et tels que cela devra donc déclarer beaucoup de variables locales temporaires qui pourraient être utilisées ou non à une certaine exécution.



1
votes

Essayez ceci: xxx

ou xxx

n'oublie pas de xxx

après.


0 commentaires