J'ai appris le C ++ et j'ai du mal à comprendre null. En particulier, les tutoriels que j'ai lus mentionnent une "vérification nulle", mais je ne sais pas ce que cela signifie ni pourquoi c'est nécessaire.
- Qu'est-ce qui est nul exactement?
- Que signifie «vérifier la nullité»?
- Dois-je toujours vérifier la null?
Tout exemple de code serait très apprécié.
Réponses:
En C et C ++, les pointeurs sont intrinsèquement dangereux, c'est-à-dire que lorsque vous déréférencez un pointeur, il est de votre responsabilité de vous assurer qu'il pointe vers un endroit valide; cela fait partie de la "gestion manuelle de la mémoire" (contrairement aux schémas de gestion automatique de la mémoire implémentés dans des langages comme Java, PHP ou le runtime .NET, qui ne vous permettront pas de créer des références invalides sans effort considérable).
Une solution courante qui détecte de nombreuses erreurs consiste à définir tous les pointeurs qui ne pointent vers rien comme
NULL
(ou, en C ++ correct0
), et à vérifier cela avant d'accéder au pointeur. Plus précisément, il est courant d'initialiser tous les pointeurs sur NULL (sauf si vous avez déjà quelque chose vers lequel les pointer lorsque vous les déclarez) et de les définir sur NULL lorsque vousdelete
oufree()
eux (sauf s'ils sortent du champ d'application immédiatement après cela). Exemple (en C, mais aussi en C ++ valide):Une meilleure version:
Sans la vérification nulle, le passage d'un pointeur NULL dans cette fonction entraînera une erreur de segmentation, et il n'y a rien que vous puissiez faire - le système d'exploitation tuera simplement votre processus et peut-être le vidage de mémoire ou affichera une boîte de dialogue de rapport de plantage. Avec la vérification nulle en place, vous pouvez effectuer une gestion des erreurs appropriée et récupérer correctement - corrigez le problème vous-même, abandonnez l'opération en cours, écrivez une entrée de journal, informez l'utilisateur, tout ce qui est approprié.
la source
Les autres réponses couvraient à peu près votre question exacte. Une vérification nulle est effectuée pour être sûr que le pointeur que vous avez reçu pointe réellement vers une instance valide d'un type (objets, primitives, etc.).
Je vais ajouter ici mon propre conseil. Évitez les contrôles nuls. :) Les contrôles nuls (et d'autres formes de programmation défensive) encombrent le code et le rendent plus sujet aux erreurs que les autres techniques de gestion des erreurs.
Ma technique préférée en ce qui concerne les pointeurs d'objets est d'utiliser le modèle Null Object . Cela signifie renvoyer une (pointeur - ou mieux encore, une référence à un) tableau ou liste vide au lieu de null, ou renvoyer une chaîne vide ("") au lieu de null, ou même la chaîne "0" (ou quelque chose d'équivalent à "rien "dans le contexte) où vous vous attendez à ce qu'il soit analysé en un entier.
En bonus, voici un petit quelque chose que vous ne saviez peut-être pas sur le pointeur nul, qui a été (formellement) implémenté par CAR Hoare pour la langue Algol W en 1965.
la source
La valeur du pointeur nul représente un "nulle part" bien défini; il s'agit d'une valeur de pointeur non valide qui est garantie de comparer inégale à toute autre valeur de pointeur. Tenter de déréférencer un pointeur nul entraîne un comportement indéfini et conduit généralement à une erreur d'exécution, vous devez donc vous assurer qu'un pointeur n'est pas NULL avant de tenter de déréférencer. Un certain nombre de fonctions de bibliothèque C et C ++ renverront un pointeur nul pour indiquer une condition d'erreur. Par exemple, la fonction de bibliothèque
malloc
renverra une valeur de pointeur nulle si elle ne peut pas allouer le nombre d'octets qui ont été demandés, et tenter d'accéder à la mémoire via ce pointeur entraînera (généralement) une erreur d'exécution:Nous devons donc nous assurer que l'
malloc
appel a réussi en vérifiant la valeur de parp
rapport à NULL:Maintenant, accrochez-vous à vos chaussettes une minute, cela va devenir un peu cahoteux.
Il existe une valeur de pointeur nul et une constante de pointeur nul , et les deux ne sont pas nécessairement les mêmes. La valeur du pointeur nul correspond à la valeur que l'architecture sous-jacente utilise pour représenter "nulle part". Cette valeur peut être 0x00000000, ou 0xFFFFFFFF, ou 0xDEADBEEF, ou quelque chose de complètement différent. Ne supposez pas que la valeur du pointeur nul est toujours 0.
La constante de pointeur nul , OTOH, est toujours une expression intégrale à valeur 0. En ce qui concerne votre code source , 0 (ou toute expression intégrale évaluée à 0) représente un pointeur nul. C et C ++ définissent la macro NULL comme constante de pointeur null. Lorsque votre code est compilé, la constante de pointeur nul sera remplacée par la valeur de pointeur nul appropriée dans le code machine généré.
Sachez également que NULL n'est qu'une des nombreuses valeurs de pointeur non valides possibles ; si vous déclarez une variable de pointeur automatique sans l'initialiser explicitement, comme
la valeur initialement stockée dans la variable est indéterminée et peut ne pas correspondre à une adresse mémoire valide ou accessible. Malheureusement, il n'existe aucun moyen (portable) de savoir si une valeur de pointeur non NULL est valide ou non avant d'essayer de l'utiliser. Donc, si vous avez affaire à des pointeurs, c'est généralement une bonne idée de les initialiser explicitement sur NULL lorsque vous les déclarez et de les définir sur NULL lorsqu'ils ne pointent activement vers rien.
Notez que c'est plus un problème en C qu'en C ++; idiomatique C ++ ne devrait pas utiliser autant de pointeurs.
la source
Il existe deux méthodes, toutes font essentiellement la même chose.
vérification nulle (vérifier si le pointeur est nul), version A
contrôle nul, version B
contrôle nul, version C
Parmi les trois, je préfère utiliser la première vérification car elle indique explicitement aux futurs développeurs ce que vous essayez de vérifier ET cela indique clairement que vous vous attendiez à ce que foo soit un pointeur.
la source
Non. La seule raison d'utiliser un pointeur en C ++ est que vous souhaitez explicitement la présence de pointeurs NULL; sinon, vous pouvez prendre une référence, qui est à la fois sémantiquement plus facile à utiliser et garantit non null.
la source
export
) et toutes les fonctionnalités de la bibliothèque C ++ 03 et TR1 et un bon morceau de C ++ 11.Si vous ne cochez pas la valeur NULL, en particulier, s'il s'agit d'un pointeur vers une structure, vous avez peut-être rencontré une vulnérabilité de sécurité - déréférence de pointeur NULL. La déréférence du pointeur NULL peut entraîner d'autres vulnérabilités de sécurité graves telles que le dépassement de tampon, la condition de concurrence ... qui peuvent permettre à un attaquant de prendre le contrôle de votre ordinateur.
De nombreux éditeurs de logiciels comme Microsoft, Oracle, Adobe, Apple ... publient des correctifs logiciels pour corriger ces vulnérabilités de sécurité. Je pense que vous devriez vérifier la valeur NULL de chaque pointeur :)
la source