Assert l’allocation d’un tableau de longueur variable

Je m’excuse pour le double possible (je n’ai pas trouvé de réponse à cela):

Avons-nous besoin de nous assurer que l’allocation d’un tableau de longueur variable s’est terminée avec succès?

Par exemple:

void func(int size) { int arr[size]; if (arr == NULL) { // Exit with a failure } else { // Continue as planned } } 

Il semble évident que la réponse est oui , mais la syntaxe arr == NULL semble un peu inhabituelle.

Merci


METTRE À JOUR:

J’admets que je n’ai pas veillé à ce que le code ci-dessus soit même compilé (en supposant que ce soit le cas).

S’il ne comstack pas, cela signifie qu’il n’y a aucun moyen d’affirmer l’affectation d’un tableau de longueur variable.

Par conséquent, je suppose que si l’allocation échoue, le programme se bloque immédiatement.

Ce serait un cas très délicat, car il est logique qu’un programme se bloque après un access illégal à la mémoire (lecture ou écriture), mais pas après une allocation de mémoire infructueuse.

Ou peut-être que l’allocation ne causera rien, mais dès que j’aurai access au tableau à une entrée qui “tombe” en dehors de la stack, je risque d’obtenir une violation d’access mémoire (comme dans un dépassement de stack) …?

Pour être honnête, je ne vois même pas comment les VLA sont alloués sur la stack si aucune autre variable locale ne les suit (les autres VLA en particulier), alors j’aimerais également obtenir une réponse à ce sujet.

Cette question découle d’une première prémisse légèrement imparfaite. Vous ne pouvez pas vérifier si un tableau est NULL car, comme dans un sujet de discussion courant, un tableau n’est pas un pointeur en C. Un tableau est l’object de stockage, en place.

Vous ne pouvez pas obtenir de code où le nom du tableau est accessible sans que le tableau ait été alloué. Un tableau local est exactement identique à toute autre variable locale: son existence est inhérente et supposée être exécutée du code environnant, et le langage ne permet pas de vérifier si un emplacement de variable donné a été “alloué” du tout. (Comme les commentaires sur la note de la question, “la stack” est une notion inférieure au niveau C sur lequel opère – le langage suppose qu’il “se produit”, par magie non spécifiée). Il faut supposer que cela réussit toujours pour que le code ait un sens au niveau le plus élémentaire.

Ce qui se produit dans le cas où le tableau ne pourrait pas être alloué est donc identique à ce qui se produit lorsque le moteur d’exécution ne peut pas allouer d’espace pour une autre variable locale – la situation est insortingnsèquement indéfinie et indéfinissable, car une hypothèse faite par le langage C machine abstraite a été violée. Le langage n’a pas de concepts (complètement formels) pouvant même l’exprimer, encore moins le vérifier ou le récupérer, de sorte que le tester est également hors de scope. Comme un débordement de stack, ceci est fondamentalement garanti pour conduire à un crash fatal.

Cela ne rend pas les VLA inutiles, pour plusieurs raisons:

  1. De nombreuses utilisations des VLA ne vont pas être énormes. Peut-être que la seule utilisation de la variante est de choisir un nombre compris entre 3 et 5? Ce n’est pas pire pour l’espace que d’utiliser quelques locales plus scalaires.

  2. Tout comme pour éviter une récursion infinie, le programmeur doit prouver certaines propriétés qu’un compilateur C ne possède pas, de même, vous devez concevoir votre programme avec au moins une limite faible sur la quantité d’espace que les VLA seront autorisés à consumr à un moment donné. Par exemple, vous pouvez vous prouver qu’aucune fonction VLA n’est jamais récursive, ni appelée à partir d’une fonction récursive, et qu’aucune d’entre elles n’utilise plus d’espace, par exemple 10K – c’est très utile et doit être sûr.

  3. Vous pouvez considérer les VLA comme une optimisation pour vous permettre d’économiser de l’espace sur lequel vous auriez sinon dû allouer un tableau local de taille statique (par exemple, dans le premier exemple, allouez toujours 5 au lieu de 3). Tant que vous connaissez et que vous concevez la limite supérieure statique, ils sont effectivement garantis de sécuriser votre programme contre les débordements, en offrant la possibilité de ne pas utiliser autant d’espace lorsque cela n’est pas nécessaire.