Quel est l'intérêt de malloc (0)?

vient de voir ce code:

artist = (char *) malloc(0);

et je me demandais pourquoi on ferait ça?

102
demandé sur Iharob Al Asimi 2010-01-07 20:43:14

16 réponses

Selon le cahier des charges, malloc(0) retournera "un pointeur null ou un pointeur unique qui peut être réussi à free()".

cela permet essentiellement de ne rien allouer, mais de passer quand même la variable" artist " à un appel à free() sans s'inquiéter. Pour des raisons pratiques, c'est à peu près la même chose que de faire:

artist = NULL;
104
répondu Reed Copsey 2010-01-07 17:47:15

Le C standard dit:

si l'espace ne peut pas être attribué, un pointeur nul est retourner. Si la taille de l'espace demandé est zéro, le comportement est implémentation défini: soit un pointeur nul est retourné, soit le comportement est comme si la taille était valeur non nulle, sauf que le pointeur retourné ne doit pas être utilisé pour accéder à un objet.

ainsi, malloc(0) pourrait retourner NULL ou un pointeur valide qui ne peut pas être déréférencé . Dans les deux cas, il est parfaitement légitime d'appeler free() .

Je ne pense pas vraiment que malloc(0) ait beaucoup d'utilité, sauf dans les cas où malloc(n) est appelé dans une boucle par exemple, et n pourrait être zéro.

en Regardant le code dans le lien, je crois que l'auteur avait deux idées fausses:

  • malloc(0) retourne a pointeur valide toujours , et
  • free(0) est mauvais.

ainsi, il s'est assuré que artist et d'autres variables ont toujours une certaine valeur "valide" en eux. Le commentaire dit aussi: // these must always point at malloc'd data .

43
répondu Alok Singhal 2010-01-25 15:46:51

malloc(0) comportement est mise en œuvre spécifique. La bibliothèque peut retourner NULL ou avoir le comportement régulier de malloc, sans mémoire allouée. Quoi qu'il fasse, il doit être documenté quelque part.

Habituellement, il renvoie un pointeur qui est valide et unique mais ne devrait pas être déréférencé. Notez également qu'il peut consommer de la mémoire même s'il n'a pas en fait allouer quoi que ce soit.

il est possible de realloc un pointeur non nul malloc(0).

avoir un malloc (0) mot à mot n'est pas très utile. Il est surtout utilisé lorsqu'une allocation dynamique est de zéro octet et que vous ne vous souciez pas de le valider.

9
répondu Coincoin 2010-01-07 18:32:29

il y a une réponse ailleurs sur cette page qui commence par "malloc(0) retournera une adresse mémoire valide et dont la portée dépendra du type de pointeur auquel on attribue de la mémoire". Cet énoncé est incorrect (Je n'ai pas assez de réputation pour commenter directement cette réponse, donc je ne peux pas mettre ce commentaire directement en dessous).

Faire des malloc(0) pas automatiquement allouer de la mémoire de taille correcte. La fonction malloc est pas au courant de ce que vous êtes casting de son résultat. La fonction malloc repose purement sur le nombre de taille que vous donnez comme argument. Vous devez faire malloc (sizeof (int)) pour obtenir assez de stockage pour contenir un int, par exemple, pas 0.

4
répondu Krellan 2014-04-16 19:15:36

il y a beaucoup de réponses à moitié vraies ici, donc voici les faits. La page d'accueil de malloc() dit:

si la taille est 0, alors malloc () renvoie soit NULL, soit une valeur de pointeur unique qui peut plus tard être passé avec succès à free ().

cela signifie qu'il n'y a absolument aucune garantie que le résultat de malloc(0) soit unique ou non nul. La seule garantie est fournie par l' définition de free() , encore une fois, voici ce que dit la page de manuel:

si ptr est nul, aucune opération n'est effectuée.

donc, quoi que malloc(0) revienne, il peut être passé en toute sécurité à free() . Mais un pointeur NULL aussi.

par conséquent, écrire artist = malloc(0); n'est en aucune façon mieux que d'écrire artist = NULL;

4
répondu cmaster 2014-04-16 19:34:58

malloc(0) n'a aucun sens pour moi, à moins que le code ne s'appuie sur un comportement spécifique à la mise en œuvre. Si le code est censé être portable, alors il doit tenir compte du fait qu'un retour nul de malloc(0) n'est pas un échec. Alors pourquoi ne pas simplement assigner NULL à artist de toute façon, puisque c'est un résultat valide et réussi, et est moins de code, et ne fera pas prendre le temps à vos programmeurs de maintenance de le comprendre?

malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO) ou malloc(some_variable_which_might_be_zero) peut-être pourrait avoir leurs utilisations, bien que encore vous devez prendre le soin supplémentaire de ne pas traiter un retour nul comme un échec si la valeur est 0, mais une taille 0 est supposée être OK.

3
répondu Steve Jessop 2010-01-07 17:57:15

Certes, je n'ai jamais vu cela avant, c'est la première fois que je vois cette syntaxe, on pourrait dire, un cas classique de surmenage de fonction. En conjonction avec la réponse de Reed, je voudrais souligner qu'il ya une chose similaire, qui apparaît comme une fonction surchargée realloc :

  • foo est non NULLE, et la taille est égale à zéro, realloc(foo, size); . Quand vous passez dans un pointeur non-NULL et une taille de zéro à realloc, realloc se comporte comme si vous aviez appelé free(…)
  • foo est NULLE et la taille est non-nul, et supérieur à 1, realloc(foo, size); . Lorsque vous passez dans un pointeur NULL et que la taille n'est pas nulle, realloc se comporte comme si vous aviez appelé malloc ( ... )

Espérons que cette aide, Meilleures salutations, Tom.

2
répondu t0mm13b 2010-01-25 16:06:50

pour répondre effectivement à la question posée: il n'y a aucune raison de faire que

2
répondu Paolo 2013-01-23 20:52:42

pourquoi tu ne devrais pas faire ça...

puisque la valeur de retour de malloc dépend de l'implémentation, vous pouvez récupérer un pointeur NULL ou une autre adresse. Cela peut finir par créer des dépassements de tampon tas-buffer si le code de gestion des erreurs ne vérifie pas à la fois la taille et la valeur retournée, ce qui entraîne des problèmes de stabilité (plantages) ou même des problèmes de sécurité plus graves.

considérons cet exemple, où un accès supplémentaire à la mémoire via l'adresse retournée va corrompre la taille du tas est zéro et implémentation renvoie une valeur non nulle.

size_t size;

/* Initialize size, possibly by user-controlled input */

int *list = (int *)malloc(size);
if (list == NULL) {
  /* Handle allocation error */
}
else {
  /* Continue processing list */
}

Voir ce Codage Sécurisé page du CERT Normes de Codage où j'ai pris l'exemple ci-dessus pour plus de lecture.

2
répondu auselen 2015-02-13 09:03:57

pas sûr, selon certains source malloc aléatoire code que j'ai trouvé, une entrée de 0 résulte en une valeur de retour de NULL. Donc c'est une façon folle de mettre le pointeur de l'artiste à NULL.

http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html

0
répondu Doug T. 2010-01-07 17:47:22

malloc (0) retournera NULL ou un pointeur valide qui peut être correctement passé à free. Et si il semble que la mémoire qu'il est inutile ou qu'il ne peut pas être écrites ou lues, qui n'est pas toujours vrai. :)

int *i = malloc(0);
*i = 100;
printf("%d", *i);

nous nous attendons à un défaut de segmentation ici, mais étonnamment, cela imprime 100! C'est parce que malloc demande en fait un énorme morceau de mémoire quand nous appelons malloc pour la première fois. Chaque appel à malloc après cela, utilise la mémoire de ce gros morceau. Seulement après que le gros morceau est terminé, une nouvelle mémoire est demandé.

utilisation de malloc(0): si vous êtes dans une situation où vous voulez que les appels subséquents de malloc soient plus rapides, appeler malloc (0) devrait le faire pour vous (sauf pour les cas de bord).

0
répondu Sagar Bhosale 2014-01-01 09:29:31

Dans Windows:

  • void *p = malloc(0); attribuera un tampon de longueur nulle au tas local. Le pointeur retourné est valide pointeur de segment.
  • malloc appelle finalement HeapAlloc en utilisant le tas D'exécution C par défaut qui appelle ensuite RtlAllocateHeap , etc.
  • free(p); utilise HeapFree pour libérer le tampon de 0 longueur sur le tas. Ne pas le libérer entraînerait une fuite de mémoire.
0
répondu sam msft 2015-10-23 03:53:17

Voici l'analyse après l'exécution avec l'outil de vérification de mémoire valgrind.

==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740==     in use at exit: 0 bytes in 0 blocks
==16740==   total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible

et voici mon code d'échantillon:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
   //int i;
   char *p1;

   p1 = (char *)malloc(0);
   printf("p1 = %p\n", p1);

   free(p1);

   return 0;

}

par défaut 1024 octets est alloué. Si j'augmente la taille de malloc, l'allocation d'octets augmentera de 1025 et ainsi de suite.

0
répondu Shubhesh Swain 2017-07-13 14:40:31

Selon Reed Copsey réponse et la page de man de malloc , j'ai écrit quelques exemples de test. Et j'ai trouvé malloc(0) donnera toujours une valeur unique. Voir mon exemple:

char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

La sortie sera "a Obtenu un pointeur valide", qui signifie ptr n'est pas nulle.

-1
répondu Neal 2017-05-23 12:18:20

malloc(0) renverra une adresse mémoire valide et dont la portée dépendra du type de pointeur auquel on attribue de la mémoire. Vous pouvez aussi assigner des valeurs à la zone mémoire, mais cela devrait être dans la plage avec le type de pointeur utilisé. Vous pouvez également libérer la mémoire allouée. Je l'expliquerai par un exemple:

int *p=NULL;
p=(int *)malloc(0);
free(p);

le code ci-dessus fonctionnera très bien dans un compilateur gcc sur une machine Linux. Si vous avez un compilateur 32 bits, alors vous pouvez fournir les valeurs dans la gamme entière, i.e. -2147483648 à 2147483647. De même pour les personnages aussi. S'il vous plaît noter que si le type de pointeur déclaré est modifié alors la gamme de valeurs changera indépendamment de malloc typecast, i.e.

unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);

p prendra une valeur de 0 à 255 de char puisqu'il est déclaré int non signé.

-3
répondu Suryakant Tiwari 2014-01-15 12:57:30

juste pour corriger une fausse impression ici:

artist = (char *) malloc(0); ne reviendra jamais NULL ; ce n'est pas la même chose que artist = NULL; . Écrivez un programme simple et comparez artist avec NULL . if (artist == NULL) est faux et if (artist) est vrai.

-3
répondu ALFRED OKORONKWO 2015-10-23 03:34:20