malloc de taille zéro

Très simple question, j’ai fait le programme suivant:

#include  int main(int argc, char ** argv) { void * ptr; ptr = malloc(0); free(ptr); } 

Et cela ne va pas mal sur ma machine. Est-ce un comportement portable de stdlib malloc et gratuit, ou est-ce que je recherche des problèmes?

Edit: Ce qui semble non portable est la valeur renvoyée par malloc. La question concerne la combinaison libre malloc (0) +, pas la valeur de ptr.

Le comportement est défini par l’implémentation, vous recevrez un pointeur NULL ou une adresse. Appeler gratuitement pour le pointeur reçu ne devrait cependant pas poser de problème puisque:

  • free (NULL) est ok, aucune opération n’est effectuée
  • free (address) est ok, si l’adresse a été reçue de malloc (ou d’autres comme calloc etc.)

Il est autorisé à renvoyer NULL, et il est permis de renvoyer un pointeur non NULL que vous ne pouvez pas déréférencer. Les deux manières sont sanctionnées par la norme (7.20.3):

Si la taille de l’espace demandé est égale à zéro, le comportement est défini par l’implémentation: un pointeur nul est renvoyé ou le comportement est comme si la taille présentait une valeur différente de zéro, sauf que le pointeur renvoyé ne devait pas être utilisé pour accéder à un object. .

Désolé pour le problème, j’aurais dû lire les pages de manuel:

malloc () alloue des octets de taille et renvoie un pointeur sur la mémoire allouée. La mémoire n’est pas effacée. Si la taille est 0, alors malloc () renvoie soit NULL, soit une valeur de pointeur unique pouvant être transmise ultérieurement à free ().

free () libère l’espace mémoire pointé par ptr, qui doit avoir été renvoyé par un précédent appel à malloc (), calloc () ou realloc (). Sinon, ou si free (ptr) a déjà été appelé auparavant, un comportement non défini se produit. Si ptr est NULL, aucune opération n’est effectuée.

Il semble que ce soit vrai au moins pour le gnu libc

Selon le c standard

7.20.3 Si la taille de l’espace demandé est égale à zéro, le comportement est défini par l’implémentation: soit un pointeur nul est renvoyé, soit le comportement est comme si la taille présentait une valeur différente de zéro, sauf que le pointeur renvoyé ne devait pas être utilisé pour accéder un object.

Mise à jour en tenant compte des commentaires de libt & Pax:

L’appel de malloc (0) dépend de l’implémentation ou, en d’autres termes, il est non portable et indéfini.

Lien vers la question CFaq pour plus de détails.

Bien que cela puisse être légal en C / C ++, cela indique des problèmes plus importants. Je l’appelle généralement «la pente du pointeur».

Voir “Ne faites pas d’hypothèses sur le résultat de malloc (0) ou calloc (0)”, https://www.securecoding.cert.org/confluence/display/seccode/VOID+MEMxx-A.+Do+not+ make + hypothese + about + the + result + of + malloc% 280% 29 + ou + calloc% 280% 29 .

Dans mon expérience, j’ai vu que malloc (0) renvoie un pointeur qui peut être libéré. Mais, cela provoque SIGSEGV dans les instructions malloc () ultérieures. Et c’était très aléatoire.

Lorsque j’ai ajouté un chèque, pour ne pas appeler malloc si la taille à atsortingbuer est zéro, je me suis débarrassé de cela.

Donc, je suggère de ne pas allouer de mémoire pour la taille 0.

-Ashutosh