Contexte de la question : Le langage C a toujours été flexible en matière de conversion de types, facilitant ainsi le travail avec la mémoire de bas niveau et diverses plateformes. Cependant, sa concision et sa puissance peuvent facilement conduire à des vulnérabilités et des défauts associés à une conversion de types incorrecte, notamment lors de l'utilisation de pointeurs et d'arithmétique binaire.
Problème :
Solution :
Exemple de code :
#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Valeur : %d ", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // Accès à la mémoire brute : autorisé si ptr pointe vraiment sur un int
Caractéristiques clés :
1. Quand est-il permis de convertir un void en pointeur vers une structure, et est-ce toujours sûr ?*
Cette conversion est sûre si l'adresse pointe réellement sur une instance de cette structure, sinon le comportement est indéfini.
2. Que se passe-t-il si on convertit un pointeur vers une structure d'une certaine taille en un pointeur vers une structure avec un nombre inférieur ou supérieur de champs ?
L'accès aux champs de la "nouvelle" structure entraînera une lecture/écriture en dehors des limites de la structure d'origine, ce qui peut provoquer une corruption des données.
Exemple de code :
typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b — accès à "des déchets"
3. Peut-on convertir en toute sécurité un pointeur vers int en un pointeur vers char pour accéder aux octets de ce nombre ?
C'est l'une des techniques typiques de manipulation de la mémoire : l'accès par octets est permis, mais nécessite de la prudence, car il peut y avoir des problèmes d'alignement et l'ordre des octets dépend de l'architecture (big-endian/little-endian).
Un jeune programmeur a optimisé le temps d'accès en traitant un paquet réseau, en convertissant un pointeur depuis un tableau brut vers un pointeur vers une structure de données avec des champs de types différents.
Avantages :
Inconvénients :
Après retravail, chaque octet du paquet était extrait manuellement via memcpy.
Avantages :
Inconvénients :