43 votes

Si `malloc (0)` renvoie un pointeur non null, puis-je le transmettre à `free`?

J'ai lu au cours des discussions de la façon dont malloc se comporte lorsque vous demandez un zéro de la taille de bloc.

Je comprends que le comportement de l' malloc(0) est mise en œuvre définis, et il est censé retourner un pointeur null, ou un pointeur non null que je suis néanmoins pas censé accès. (Ce qui est logique, car il n'y a aucune garantie qu'il se dirige à toute la mémoire utilisable.)

Toutefois, si une telle nonaccessable pointeur non null, suis-je autorisé à passer à l' free de la façon habituelle? Ou est-ce illégal, car le pointeur-je obtenir à partir d' malloc(0) peut pas pointer vers un bloc alloué de la mémoire?

Concrètement, le code suivant est bien définie comportement:

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

int main() {
    int* x = (int*) malloc(0);
    if (x == NULL) {
        printf("Got NULL\n");
        return 0;
    } else {
        printf("Got nonnull %p\n", x);
    }
    free(x); // is calling `free` here okay?
}

41voto

apriori Points 31

Le standard C99 (en fait WG14/N1124. Comité De Projet -- 6 Mai 2005. ISO/IEC 9899:TC2) dit à propos de l' malloc():

Le pointeur retourné points de départ (le plus faible de l'octet l'adresse) de l'espace alloué. Si l'espace ne peut pas être attribué, un pointeur null est retournés. Si la taille de l'espace requis est égal à zéro, le comportement est définie par l'implémentation: soit un pointeur null est retourné, ou le comportement est comme si la taille avait quelques valeur différente de zéro, sauf que le pointeur retourné ne doit pas être utilisé pour accéder à un objet

et à propos de free():

Sinon, si l'argument ne correspond pas à un pointeur retourné plus tôt par le calloc, malloc, ou en fonction realloc, ou si l'espace a été libéré par un appel gratuit ou realloc, le comportement est indéfini.

IEEE Std 1003.1-2008 (POSIX), 2016 Édition dit à propos de l' free():

Le free() la fonction est de provoquer l'espace pointé par ptr pour être libéré; c'est, mis à disposition pour plus d'allocation. Si ptr est un pointeur null, aucune action ne pourra se produire. Sinon, si l'argument ne ne pas correspondre à un pointeur précédemment renvoyée par une fonction POSIX.1-2008 date de qui alloue de la mémoire comme si par malloc(), ou si l'espace a été libéré par un appel à free() ou realloc(), le comportement est undefined.

Donc, quel que soit *alloc() retours, vous pouvez passer à l' free().

Comme pour les implémentations actuelles de l' malloc():

FreeBSD utilise le contribué jemalloc qui ne

void *
je_malloc(size_t size)
{
    void *ret;
    size_t usize JEMALLOC_CC_SILENCE_INIT(0);

    if (size == 0)
        size = 1;
    [...]

Alors que Apple ne libmalloc

void *
szone_memalign(szone_t *szone, size_t alignment, size_t size)
{
    if (size == 0) {
        size = 1; // Ensures we'll return an aligned free()-able pointer
    [...]

La GLIBC également de modifier la taille demandée; c'est à l'aide d'un appel de cette macro à la demande de la taille, en octets, en tant que paramètre à aligner la taille de certaines limites ou tout simplement le minimum de la taille d'allocation:

#define request2size(req)                                       \
    (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?         \
    MINSIZE :                                                   \
    ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

24voto

Malcolm McLean Points 5437

Oui, en fait, vous devez le faire pour éviter une fuite de mémoire probable.

Le système malloc renvoie généralement un bloc de contrôle masqué dans l'espace situé juste avant le pointeur, avec des informations telles que la taille de l'allocation. Si la taille d'allocation est égale à zéro, ce bloc existe toujours et occupe de la mémoire, si malloc renvoie non nul.

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