ProgrammationDéveloppeur C

Parlez en détail du mécanisme de transmission des tableaux aux fonctions en C. Quels sont les risques associés à ce modèle et comment organiser correctement un travail sécurisé avec les tableaux à l'intérieur des fonctions ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En C, les tableaux ne sont pas passés aux fonctions par valeur. Lorsqu'un tableau est passé en tant qu'argument, ce qui est réellement transmis à la fonction est un pointeur vers le premier élément du tableau. Cela signifie que la fonction modifie le tableau d'origine, et non sa copie.

Par exemple :

void fillArray(int arr[], int n) { for (int i = 0; i < n; ++i) arr[i] = i*i; } int main() { int myarr[5]; fillArray(myarr, 5); // ok }

À l'intérieur de la fonction :

  • il est impossible de connaître la taille du tableau d'origine via sizeof(arr) — cela renverra la taille du pointeur, et non celle du tableau.
  • On ne peut travailler qu'avec le morceau de mémoire dont la taille a été explicitement passée.

Pour travailler correctement et en toute sécurité avec des tableaux, il est possible de :

  • toujours transmettre explicitement la taille du tableau en tant qu'argument séparé;
  • utiliser des constantes ou des macros d’enveloppe pour les tailles;
  • si vous devez protéger le tableau contre les modifications, passez const int *arr.

Question piège

Question : Est-il possible de connaître la taille du tableau original passé à la fonction par l'argument int arr[] via sizeof(arr) ?

Réponse : Non, ce n'est pas possible ! sizeof(arr) à l'intérieur de la fonction renverra la taille du pointeur de type (par exemple, 4 ou 8 octets), et non la taille du tableau.

Exemple :

void f(int arr[]) { printf("%zu\n", sizeof(arr)); // taille du pointeur, pas du tableau ! } int main() { int x[10]; f(x); // Affiche généralement 8 (x86_64) ou 4 (x86) }

Exemples d'erreurs réelles


Histoire

Dans un projet industriel, les fonctions de copie de tableaux tentaient de calculer la longueur du tableau à la volée, en utilisant sizeof(arr)/sizeof(int) à l'intérieur de la fonction. En pratique, cela conduisait à la copie uniquement d'une partie du tableau, car la taille était toujours égale à 1 (8/8), et les données étaient écrasées de manière imprévisible.


Histoire

Dans une application réseau, la fonction d'envoi de données prenait un tampon sous forme de tableau sans indiquer explicitement sa taille, ce qui provoquait l'envoi incomplet du tampon ou des lectures hors limites du tableau, ce qui entraînait des erreurs de transmission et une instabilité de la connexion.


Histoire

Lors de l'écriture d'une bibliothèque pour le traitement d'images, un programmeur n'a pas fourni à la fonction de coloration du tableau d'images un paramètre obligatoire pour la taille. Cela a conduit à un débordement de tampon et à un plantage du programme sur certaines entrées, ce qui n'a été découvert que lors du test d'intégration sur une grande image.