30 votes

Est-il nécessaire de vérifier la présence de NULL après l'allocation de la mémoire, lorsque le noyau utilise la mémoire overcommit

Il est d'usage de vérifier la présence de NULL (si la mémoire a été allouée avec succès) après un malloc(), quelque chose comme

void *ptr = malloc(10);    
if (ptr != NULL) {  
  // do some thing usefull  
} else {  
 // no memory. safely return/throw ...  
}  

avec l'overcommit mémoire activé dans le noyau, y a-t-il une chance d'obtenir NULL ? Dois-je suivre la pratique de vérifier religieusement NULL pour chaque allocation ? Est-ce que malloc retournera NULL malgré le mécanisme d'overcommit agressif (je suppose la valeur 1) ?

En fait, le noyau Android utilise l'overcommit de mémoire (je ne suis pas sûr de la valeur, j'aimerais bien la connaître (valeur de l'overcommit) et sa signification). Une partie du code source (C/C++) du framework Android (qui pourrait être une tierce partie) ne vérifie pas la présence de NULL et n'attrape pas bad_alloc après les allocations. Est-ce qu'il me manque quelque chose ?

Il y a quelques fils de discussion dans SO concernant la mémoire overcommit, mais aucun d'entre eux n'a résolu ma confusion.

EDIT : Si l'overcommit agressif est utilisé, NULL ne sera pas retourné (hypothèse 1). Quand il n'y a pas de mémoire physique disponible et que l'on essaie d'accéder à la mémoire allouée (écrire dans la mémoire allouée), l'OOM va tuer un processus et allouer de la mémoire pour l'application jusqu'à ce qu'elle soit tuée à son tour (hypothèse 2). Dans les deux cas, je ne vois pas la nécessité de vérifier NULL (mémoire allouée ou processus tué). Est-ce que j'ai raison dans mes hypothèses ?
La portabilité n'est pas une préoccupation pour cette question.

38voto

Charles Bailey Points 244082

Oui, vous devez toujours vérifier les échecs renvoyés par malloc . Dans un environnement qui surcommande la mémoire, vous ne serez pas en mesure de détecter et de récupérer les défaillances dues à l'épuisement de l'espace de stockage physique requis lorsque vous écrivez dans des parties de l'espace d'adressage qui ont été allouées à votre programme par un appel précédent à la fonction malloc .

Cependant, ce n'est pas le seul problème qui pourrait causer un malloc d'échouer dans un environnement traditionnel. Une demande de bloc de mémoire particulièrement important, alors que l'espace d'adressage de votre programme est fragmenté, peut échouer même si la mémoire physique totale est potentiellement suffisante pour satisfaire la demande. Parce qu'il n'y a pas de plage contiguë d'espace d'adressage libre. malloc doit échouer. Ce type d'échec doit être signalé par malloc en retournant sur NULL si l'environnement surcharge ou non la mémoire.

7voto

osgx Points 28675

Vous devez vérifier la valeur de retour pour NULL chaque temps. Toute fonction de bibliothèque peut échouer. Même fclose() le fait (sur un partage NFS déconnecté, et une erreur de fclose d'un fichier NFS signifie que les données n'ont pas été sauvegardées).

La plupart des logiciels sont mal écrits et ne contiennent pas tous les contrôles.

malloc ne peut pas retourner autre chose que NULL ou un pointeur. Tout ou rien. Vous ne pouvez pas obtenir 1 octet de malloc si vous en demandez 10.

3voto

t0mm13b Points 21031

Il est conseillé de vérifier religieusement la présence de NULL dans tous les appels de fonctions susceptibles de retourner NULL, que le noyau dispose ou non d'une mémoire surcommittable.

Le segment de code suivant montre comment vérifier si l'appel à malloc a fonctionné ou non...

void \*ptr = malloc(10);
if (ptr != NULL){
   /\* Do something here with ptr \*/
}else{
   /\* Do something here if it fails \*/
}

Les opérations sur les fichiers, les opérations sur la mémoire, pour n'en citer que quelques-unes, renverront un NULL en cas d'échec.

J'espère que cela vous aidera, Meilleures salutations, Tom.

1voto

Eh bien... sous Linux, étant donné que la mémoire n'est pas sauvegardée par page (initialement) et ne crée une sauvegarde par page qu'après la première lecture/écriture, le système d'exploitation réussira toujours à vous donner de la mémoire (sauf si vous avez épuisé l'espace d'adressage, ce qui n'est pas possible dans les systèmes 64 bits). Ainsi, s'il manque de mémoire et ne peut pas vous donner la mémoire promise, le tueur OOM tuera simplement votre application ou une autre application pour vous donner la sauvegarde de page dont vous avez besoin. Donc, que vous fassiez la vérification NULL ou non, le résultat est le même, un crash........

-5voto

Shaoquan Points 10

Non, il n'est pas nécessaire de vérifier le résultat de malloc.

Bien avant que malloc ne tombe en panne, le système d'exploitation avait déjà rencontré de nombreux problèmes.

"OOM-Killer et overcommit" serait un meilleur choix.

Quoi ? Votre système d'exploitation ne supporte pas "OOM-Killer et overcommit" ?

C'est pourquoi vous devriez passer à Linux (ou Android) !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X