Échange de 2 pointeurs de chaîne avec une fonction dont les parameters sont nuls **

Le code suivant ne comstack pas:

void swap(void **p, void **q) { void *tmp; tmp = *p; *p = *q; *q = tmp; } int main(void) { char *s[] = {"help" , "please"}; swap(&s[0], &s[1]); return 0; } 

Bien que ce code soit compilé et fonctionne parfaitement:

 void swap(void **p, void **q) { void *tmp; tmp = *p; *p = *q; *q = tmp; } int main(void) { char *s[] = {"help" , "please"}; swap((void **) &s[0], (void **) &s[1]); return 0; } 

Pourquoi le casting est-il nécessaire?

Oui, donc en plus des réponses déjà existantes qui soulignent que void ** n’est pas identique à char ** : votre code invoque un comportement non défini en raison des types de pointeurs incompatibles. Voici ce que vous voulez réellement:

 void swap(void *p1, void *p2, size_t size) { unsigned char buf[size]; memcpy(buf, p1, size); memcpy(p1, p2, size); memcpy(p2, buf, size); } 

Et appelez ça comme ça:

 const char *s[] = { "help", "please" }; // also note the use of `const' for ssortingng literals swap(&s[0], &s[1], sizeof(s[0])); 

Vous avez une erreur d’affectation de pointeur incompatible dans le premier code. En C, le type d’un littéral de chaîne est char[N] où N est le nombre de caractères. Dans la plupart des expressions, note char[N] se désintègre facilement en caractère char*

Selon votre déclaration, char *s[] = {"help" , "please"}; type de s[i] est char* (en fait, char[N] décompose en char* ).

Lorsque vous passez &s[i] vous passez un caractère char** incompatible avec void** . Le second code fonctionne parce que vous avez transtypé dans void** lors de l’appel de fonction.

void* peut être affecté à n’importe quel type d’adresse mais à son adresse void** laquelle doit être assignée l’adresse de la variable de type void* .

Si vous ne possédez qu’un tableau de chaînes, alors dans la première version de la fonction swap, vous pouvez remplacer void par caractère, vous pouvez donc le faire sans conversion de type.

La conversion rend l’exemple compilé à cause de ce que vous transmettez à la fonction.

char *var[]; est à bien des égards identique à char **var;

Ceci étant dit, vous transmettez à la fonction une référence / adresse à l’un des membres du tableau ( s[0] ).

Un autre problème plus important est que la fonction accepte les pointeurs de vide et que des pointeurs de caractère sont transmis (sans le transtypage).