web-dev-qa-db-fra.com

Est-ce que malloc () initialise le tableau alloué à zéro?

Voici le code que j'utilise:

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

int main() {
    int *arr;
    int sz = 100000;
    arr = (int *)malloc(sz * sizeof(int));

    int i;
    for (i = 0; i < sz; ++i) {
        if (arr[i] != 0) {
            printf("OK\n");
            break;
        }
    }

    free(arr);
    return 0;
}

Le programme n'imprime pas OK. malloc n'est pas supposé initialiser la mémoire allouée à zéro. Pourquoi cela arrive-t-il?

5
devil0150

La page de manuel de malloc dit:

La fonction malloc () alloue des octets de taille et renvoie un pointeur sur la mémoire allouée. La mémoire n'est pas initialisée. Si la taille est 0, alors malloc () renvoie NULL ou une valeur de pointeur unique pouvant plus tard être passé avec succès à free ().

Donc, malloc() renvoie mémoire non initialisée, dont le contenu est indéterminé.

 if (arr[i] != 0)

Dans votre programme, vous avez essayé d'accéder au contenu d'un bloc de mémoire, appelé comportement non défini.

9
M.S Chaudhari

malloc n'est pas censé initialiser la mémoire allouée à zéro. 

La mémoire allouée par malloc est non initialisée. La valeur à ces endroits est indéterminée. Dans ce cas, accéder à cette mémoire peut entraîner un comportement indéfini si la valeur à cet emplacement doit être une représentation d'interruption pour le type. 

n1570-§6.2.6.1 (p5):

Certaines représentations d'objet ne doivent pas nécessairement représenter une valeur du type d'objet. Si la valeur stockée d'un objet a une telle représentation et est lue par une expression lvalue qui n'a pas de type de caractère, le comportement est indéfini. [...]

et la note de bas de page dit: 

Ainsi, une variable automatique peut être initialisée à une représentation d'interruption sans provoquer de comportement indéfini, mais la valeur de la variable ne peut pas être utilisée tant qu'une valeur correcte n'y est pas stockée.

Si le comportement n'est pas défini, vous ne pouvez rien attendre de bon. Vous pouvez ou non obtenir le résultat attendu.

6
haccks

malloc n'est pas supposé initialiser la mémoire allouée à zéro. Pourquoi cela arrive-t-il?

Voici comment il a été conçu il y a plus de 40 ans.

Mais, au même moment, la fonction calloc() a été créée. Initialise la mémoire allouée à zéro et c'est la méthode recommandée pour allouer de la mémoire aux tableaux.

La ligne:

arr = (int *)malloc(sz * sizeof(int));

Devrais lire:

arr = calloc(sz, sizeof(int));

Si vous apprenez le C à partir d'un ancien livre, il vous apprendra toujours à attribuer la valeur renvoyée par malloc() ou calloc() (un void *) au type de la variable à laquelle vous affectez la valeur (int * dans votre cas). Ceci est obsolète, si la valeur renvoyée par malloc() ou calloc() est directement assignée à une variable, les versions modernes de C n'ont plus besoin de cette conversion.

3
axiac

À partir de la norme C 7.22.3.4:

Synopsis

#include <stdlib.h>
void *malloc(size_t size);

La description

La fonction malloc alloue de l'espace pour un objet de taille spécifié par la taille et dont la valeur est indéterminée.

La valeur est indéterminé . Ainsi, chaque compilateur est libre de se comporter comme il le souhaite. Par exemple, dans Microsoft Visual C++, en mode Debug, la zone de mémoire allouée par malloc() est définie sur 0xCDCDCDCD et en mode Release, elle est aléatoire. Dans les versions modernes de GCC, il est défini sur 0x000000 si vous n'activez pas les optimisations de code et aléatoire dans les autres cas. Je ne connais pas les autres compilateurs, mais vous voyez l'idée.

2
Ryan B.

void *malloc(size_t size) est juste censé garder de côté la quantité d'espace spécifiée. C'est tout. Il n'y a aucune garantie quant à ce qui sera présent dans cet espace.

Cité des pages de manuel:

La fonction malloc() alloue des octets de taille et renvoie un pointeur sur la mémoire allouée. La mémoire n'est pas initialisée. Si size est 0, alors malloc() renvoie NULL ou une valeur de pointeur unique pouvant contenir plus tard être passé avec succès à free().

En plus de calloc(), vous pouvez utiliser la fonction memset() pour mettre à zéro un bloc de mémoire.

2
babon

La première fois que vous appelez malloc(3), il demande au système d’exploitation d’obtenir de la mémoire pour l’espace mémoire.

Pour des raisons de sécurité, le noyau unix/linux (et de nombreux autres systèmes d’exploitation) renvoie en règle générale le contenu de la page à attribuer à un processus. anciens mots de passe, ou des choses similaires).

Si vous effectuez plusieurs affectations et libérations de mémoire, lorsque le module malloc réutilisera la mémoire précédente, vous verrez des déchets provenant de malloc(3).

0
Luis Colorado