Dois-je vérifier si la fonction malloc() a été un succès?
Doit-on vérifier après chaque malloc() si elle a été un succès? Est-il possible qu'un malloc() échoue? Ce qui arrive ensuite?
À l'école on nous a dit que nous devrions vérifier, c'est à dire.:
arr = (int) malloc(sizeof(int)*x*y);
if(arr==NULL){
printf("Error. Allocation was unsuccessful. \n");
return 1;
}
Qu'est-ce que la pratique sur cette question? Puis-je faire de cette façon:
if(!(arr = (int) malloc(sizeof(int)*x*y))
<error>
- En théorie, oui. En réalité, si la fonction malloc échoue, le système d'exploitation est probablement sur le point de se bloquer. PS: Votre deuxième exemple est beaucoup plus difficile à lire que le premier et doit être rejetée par une révision du code.
arr = (int) malloc(...)
est faux,malloc
retourne un pointeur. En dehors de cela: oui, vous devez vérifier s'il échoue, car il peut échouer. en outre, le casting de sa valeur de retour est dangereux.- 1. Vous n'avez pas besoin de la fonte. 2. Oui vérifier pourquoi pas
- Je dirais que c'est oui dans la théorie et dans la pratique, en particulier lorsque les gros tampons sont alloués.
- Vrai. Mais si vous allouer une mémoire tampon si grande que malloc peut échouer, alors je dirais un nouveau design est en ordre.
- Normalement oui, je suis d'accord. Mais on peut venir avec une application qui utilise le plus de mémoire possible". Mais ma principale raison pour le commentaire que quelqu'un pourrait mal lu votre remarque que "dans la pratique, ne cochez pas". (C'est une autre question si on doit ajouter
if
à chaquemalloc
ou tout simplement l'enveloppe et mettre fin à l'application avec un bon message.) - pratique, ne cochez pas la case" je dirais que, "dans la pratique, parfois c'est bien de ne pas vérifier, car il finit par encombrer le code de l'espace et si l'affectation de 10 octets échoue, votre programme est déjà en panne ou est sur le point de". Note: je écrire du code pour être comme à tolérance de panne possible: je regarde des deux côtés lors de la traversée d'une rue à sens unique.
Vous devez vous connecter pour publier un commentaire.
Pas besoin de cast
malloc()
. Oui, il est nécessaire de vérifier si la fonction malloc() a été un succès ou pas.Disons
malloc()
a échoué et que vous tentez d'accéder au pointeur de penser que la mémoire est allouée va conduire à la chute.Donc il mieux de prendre de la mémoire de l'attribution de l'échec avant d'accéder au pointeur.malloc(sizeof(int))
et pas OPmalloc(sizeof(int)*x*y)
. Les essais contreNULL
est suffisante pour cesizeof(int)
, mais mauvais pour les OPsizeof(int)*x*y
. Devraitx*y
--> 0, unNULL
retour est conforme code et n'indique pas une allocation de mémoire. Mieux utiliserif(arr == NULL && x != 0 && y != 0)
.Surtout ne fait qu'ajouter à l'existant réponse, mais je comprends où vous venez, si vous faites beaucoup de l'allocation de la mémoire de votre code finit par regarder très laid, avec tous les contrôles d'erreur pour le malloc.
Personnellement, j'ai souvent contourner ce problème à l'aide d'un petit malloc wrapper qui ne seront jamais échouer. À moins que votre logiciel est à la résilience, de sécurité critiques du système, vous ne pouvez pas véritablement le travail autour de malloc faute de toute façon, alors je suggère quelque chose comme ceci:
Qui permettra au moins de s'assurer que vous obtenez un message d'erreur et propre de collision, et d'éviter la majeure partie de l'erreur de code de vérification.
Pour une solution générique pour les fonctions qui peuvent échouer j'ai aussi tendance à mettre en œuvre un simple macrosuch comme ceci:
Qui permet d'exécuter une fonction comme:
Qui vous donne une seule ligne, en évitant encore une fois l'essentiel tout en permettant des contrôles appropriés.
PrintDie
doit appelerabort
, pasexit
. Parce qu'il serait plus simple de debug (sur Linux, vous aurez encore uncore
dump, qui vous pourriez analyser post-mortem avecgdb
)if(NULL == AllocMem)
est le mauvais critère. AvecMemSize == 0
, la réception d'unmalloc()
valeur de retour deNULL
est comportement conforme et pas un échec d'allocation. Changer deif(NULL == AllocMem && MemSize != 0)
des correctifs.NULL
ou certains pointeur non null lesquelles vous pouvezfree(3)
mais pas de déréférencement. POSIX est également conforme à la norme C, sauf qu'il spécifie le réglage deerrno
en cas d'échec, ce qui semble tout à fait inutile pour moi depuisENOMEM
est le seul code d'erreur, mais je suppose que vous pourriez faireerrno = 0; ptr = malloc(...); if(errno) abort()
. Ressemble encore à un bon tour pour moi.