Récemment, je travaille sur un programme de lecteur vidéo sous Windows pour un programme CCTV. Comme le programme doit décoder et jouer de nombreux flux de vidéos en même temps, je pense que cela pourrait répondre à la situation que Malloc échouera et j'ajouterai la vérification après chaque Malloc. P>
Mais en général, dans ce code de programmes open source que j'ai lu dans des projets open source, je trouve rarement une vérification du résultat de MALLOC. Ainsi, lorsque MALLOC échoue, la plupart des programmes vont simplement planter. N'est-ce pas l'unacceptalbe? P>
Mes collègues qui écrivent des programmes de serveur sur Linux alloueront une mémoire suffisante pour 100 connexions client. Donc, bien que son programme puisse refuser le client 101, il ne rencontrera jamais un échec de MALLOC. Son approche est-elle également adaptée aux applications de bureau? P>
8 Réponses :
Pour utiliser le résultat de MALLOC sans vérifier pour NULL est inacceptable dans le code qui pourrait être ouvert à utiliser sur des plates-formes où MALLOC peut échouer, sur ceux qu'il aura tendance à entraîner des accidents et des comportements imprégnés. Je ne peux pas renseigner l'avenir, je ne sais pas où mon code ira, alors j'écrirais du code avec des chèques pour Malloc renversant NULL - Mieux vaut mourir que de se comporter imprégné! P>
Stratégies de quoi faire si Malloc échoue sur le type d'appliciation et la confiance que vous avez dans les bibliothèques que vous utilisez. Certaines situations que la seule chose sûre à faire est d'arrêter tout le programme. P>
L'idée de préalculer un quota connu de mémoire et de la traversée dans certains morceaux, d'où la direction de la direction d'épuisement de la mématique est une bonne, si l'utilisation de la mémoire de votre application est prédicable. Vous pouvez l'étendre pour écrire vos propres routines de gestion de la mémoire à utiliser par votre code. p>
sur Linux, sur les OSES qui soutiennent les défaillances, j'ai vu deux modèles généraux: p>
Écrivez une procédure personnalisée qui vérifie le résultat de stocker une liste globale d'allocations "purge-capables", telles que les caches, qui peuvent être effacées en cas d'échec de l'allocation. Ensuite, essayez à nouveau l'allocation et s'il échoue toujours, signalez-le via les mécanismes de rapport d'erreur standard (qui n'effectuent pas d'allocation dynamique). P> LI>
ul> malloc () code> n'échouera jamais - au lieu de cela, le tueur OMM sera déclenché et commencera à tuer des processus aléatoires jusqu'à ce que le système tombe. Depuis que Linux est le dérivé UNIX le plus populaire utilisé aujourd'hui, de nombreux développeurs ont appris à ne jamais vérifier le résultat de MALLOC () code>. C'est probablement pourquoi vos collègues ignorent malloc () code> échecs. P>
MALLOC () code> et des appels abandon () code> si l'allocation a échoué. Par exemple, le Les bibliothèques GLIB et GTK + utilisent cette approche. P> LI>
La pratique de ne pas vérifier la valeur de retour de MALLOC a fait beaucoup plus de temps que Linux. Il est lié à la mentalité de ne pas vérifier la valeur de retour de printf - quelles sont les chances que l'une d'entre elles échouera? Mais la page d'homme pour MALLOC répertorie le comportement OOM comme un "bogue" et décrit un moyen de le désactiver afin que Malloc renvoie NULL en cas de défaillance.
@Barry: Je ne vérifie pas la valeur de retour de printf () code>, pas parce que je pense que c'est infaillible, mais parce que je ne me soucie pas si elle échoue ou non.
Lorsque vous dites que cela ne peut pas échouer, vous voulez vraiment dire qu'il n'a pas échoué gracieusement de manière à ce que le programme puisse gérer ou contrôler. Voir cette discussion ubuntuforums.org/archive/index.php/t-1214975.html
@John Millikin: Vous ne vérifiez pas la valeur de retour de printf () car elle ne renvoie pas d'état d'erreur, il renvoie simplement le nombre de caractères. Donc, cet argument est faux.
@Clifford: Si le nombre de caractères de sortie est inférieur au nombre que je m'attendais à écrire, alors il a échoué.
Pour être exact, cela peut échouer mais il ne retourne jamais NULL.
Il est facile de provoquer MALLOC code> pour renvoyer NULL sur un système Linux - Il suffit de définir une limite de mémoire de processus avec ulimit code> avant d'exécuter votre programme. Ceci est utile si vous souhaitez tester comment votre programme gère le boîtier de mémoire.
-1 La première phrase est fausse de la première phrase. La déclaration correcte serait "dans la configuration par défaut sur Linux, malloc code> parfois i> réussira même lorsque la mémoire n'est pas disponible, entraînant le programme d'appel ou un autre programme étant tué à un plus tard, heure imprévisible par le noyau Oom Killer. " Même avec Overcommit activé, MALLOC CODE> peut toujours facilement échouer, par ex. lorsque vous utilisez l'espace d'adressage virtuel.
Cette réponse devrait être non acceptée ou au moins reformulée. malloc code> pourrait absolument échouer. Par exemple, si je demande un appareil intégré avec 512 Mo de mémoire et aucun échange pour un morceau de 1 Go, il ne va pas fonctionner, et malloc code> échouera en fait en retournant NULL.
Même sur Linux, ulimit peut être utilisé pour obtenir une déclaration d'erreur MALLOC rapide. C'est juste que cela par défaut est illimité. P>
Il existe une pression définie pour être conforme aux normes publiées. Sur la plupart des systèmes, à long terme, et éventuellement même sur Linux, MALLOC (3) < / code> retournera une indication correcte de l'échec. Il est vrai que les systèmes de bureau ont une mémoire virtuelle et une pagination à la demande, mais même de ne pas vérifier MALLOC ( 3) code> ne fonctionne que dans un programme débogué sans fuites de mémoire. Si quelque chose ne va pas, quelqu'un voudra définir un ulimit code> et le suivre. Soudainement, le chèque malloc code> a un sens. P>
Vérifiez toujours et pré-allouez un tampon pouvant être libéré dans ce cas afin de pouvoir prévenir l'utilisateur à enregistrer ses données et à fermer l'application. p>
Cela dépend du type d'application sur lequel vous travaillez. Si l'application fonctionne qui est divisée en tâches discrètes dans lesquelles une tâche individuelle peut être autorisée à échouer, la vérification des allocations de mémoire peut être récupérée de gracieusement. P>
Mais dans de nombreux cas, le seul moyen raisonnable de réagir à un échec MALLOC est en terminant le programme. Permettre à votre code de bloquer simplement sur la désarférence inévitable null atteindra cela. Il serait certainement toujours préférable de vider une entrée de journal ou un message d'erreur expliquant l'erreur, mais dans le monde réel, nous travaillons sur des horaires limités. Parfois, le retour sur investissement de la manipulation des erreurs de Pedantic n'est pas là. P>
dépend de l'application que vous écrivez. Bien sûr, vous devez toujours vérifier la valeur de retour de MALLOC (). Cependant, la manipulation de l'OMS gracieusement n'a de sens que dans des cas très, tels que des services de système crucial de bas niveau, ou lors de la rédaction d'une bibliothèque pouvant être utilisée. Avoir une emballeuse malloc qui aborde sur OOM est donc très fréquente dans de nombreuses applications et cadres. Souvent, ces emballages sont nommés XMALLOC () ou similaires. P>
G_MALLOCOC'S de GLIB () s'embrase également. P>
Si vous allez gérer d'énormes quantités de mémoire et que vous souhaitez faire des déclarations sur Linux comme «Maintenant, j'ai une zone de mémoire ABC et je n'ai pas besoin de la pièce B, faites-le comme vous le souhaitez», aperçu du MMAP () / Madvise () Famille de fonctions disponibles en stock Bibliothèque GNU C. En fonction de vos habitudes d'utilisation, le code peut se retrouver encore plus simple que d'utiliser MALLOC. Cette API peut également être utilisée pour aider Linux pas gaspiller la mémoire de mémoire en cache des fichiers que vous allez lire / écrire une seule fois. P>
Ils sont bien documentés dans la documentation info de GNU libc. P>
Il est généralement impossible pour un programme de gérer à court de mémoire. Qu'est ce que tu vas faire? Ouvrez un fichier et connectez-vous quelque chose? Si vous essayez d'affecter un gros bloc et que vous échouez, vous pouvez avoir une relèvement et réessayer avec un petit tampon plus petit, mais si vous ne parvenez pas à allouer 10 octets, il n'ya pas grand chose que vous puissiez faire. Et vérifier que NULL se convolute constamment le code. Pour cette raison, j'ajoute généralement une fonction personnalisée qui vérifie et abandonne l'échec: