ProgrammationDéveloppeur C

Comment le traitement des chaînes est-il implémenté en C ? Expliquez la différence entre un tableau de caractères et un pointeur vers une chaîne. Comment éviter les erreurs lors du traitement des chaînes ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Dans le langage C, les chaînes sont implémentées comme des tableaux de caractères, se terminant par un octet nul ('\0'). Exemple de déclaration d'une chaîne :

char str1[] = "hello"; // Tableau avec 6 caractères : {'h','e','l','l','o','\0'} char *str2 = "hello"; // Pointeur vers un littéral de chaîne
  • Tableau de caractères : Alloue de la mémoire pour chaque élément, y compris le zéro terminateur. Le tableau peut être modifié (s'il n'est pas const).
  • Pointeur vers une chaîne : Peut pointer vers un littéral de chaîne (qui ne peut pas être modifié), ou vers un espace mémoire alloué. Le littéral de chaîne est généralement placé dans une segment en lecture seule.

Pour éviter les erreurs :

  • Gérez correctement la mémoire (utilisez malloc, strcpy, vérifiez la taille du tampon).
  • N'utilisez pas de littéraux de chaîne pour modifier des chaînes.
  • Vérifiez que toutes les chaînes se terminent par \0.

Exemple de traitement correct d'une chaîne :

char buffer[100]; strcpy(buffer, "test"); // OK, buffer est modifiable et contient garantis '\0'

Question piégée

Quel sera le résultat de l'exécution du code suivant et quelles erreurs provoquera-t-il ?

char *str = "hello"; str[0] = 'H'; printf("%s ", str);

Réponse : Le programme conduira à un comportement indéfini, très probablement un segfault, car les littéraux de chaîne sont placés en mémoire en lecture seule. Il n'est pas possible d'écrire des valeurs à l'adresse d'un littéral de chaîne.

Exemples d'erreurs réelles dues à l'ignorance des subtilités du sujet


Histoire L'équipe a confondu les concepts de tableau de chaîne et de pointeur vers un littéral. Une fonction prenait char *output = "default"; et exécutait ensuite strcpy(output, input);, ce qui entraînait un plantage au premier lancement, car la copie se faisait dans de la mémoire en lecture seule.


Histoire Lors du traitement des réseaux, le résultat a été enregistré dans un tampon alloué avec char *buf = NULL; strcpy(buf, data);. Cela a conduit à une écriture dans une mémoire non initialisée et à un plantage de l'application.


Histoire Dans un package de localisation, l'équipe transmettait des chaînes entre les composants sans s'assurer que le caractère \0 était ajouté. Un jour, une fonction a affiché des déchets dans la console et a corrompu la structure interne de la mémoire.