¿Está malloc() inicializando la matriz asignada a cero?

4 minutos de lectura

avatar de usuario
diablo0150

Aquí está el código que estoy usando:

#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;
}

el programa no imprime OK. malloc no se supone que debe inicializar la memoria asignada a cero. ¿Por qué está pasando esto?

  • El contenido de la memoria es indeterminado. Eso podría ser aparentemente aleatorio. o eso podría sean todos ceros. Simplemente no lo sabes de antemano.

    – Un tipo programador

    26 de julio de 2017 a las 10:14

  • “El programa no imprime bien. Se supone que malloc no debe inicializar la memoria asignada a cero”. – Tampoco se supone que lo garantice. no es todo cero De cualquier manera, al leer valores indeterminados, su programa tiene un comportamiento indefinido. No puedes esperar nada.

    – StoryTeller – Unslander Mónica

    26 de julio de 2017 a las 10:16


  • Además, las compilaciones de depuración pueden hacer que la memoria que asigne, o incluso las variables locales, se ser inicializado Para que los problemas de memoria y puntero sean más fáciles de detectar.

    – Un tipo programador

    26 de julio de 2017 a las 10:16

  • @Someprogrammerdude: el estándar C no define si un tipo tiene valores de captura o no. Y si se lee un valor de trampa, el comportamiento no está definido explícitamente. Así que creo que es UB por todas partes.

    – StoryTeller – Unslander Mónica

    26 de julio de 2017 a las 10:25

  • @StoryTeller Probablemente tienes un punto allí.

    – Un tipo programador

    26 de julio de 2017 a las 10:27

avatar de usuario
ryan b

Del estándar C 7.22.3.4:

Sinopsis

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

Descripción

La función malloc asigna espacio para un objeto cuyo tamaño se especifica por tamaño y cuyo valor es indeterminado.

el valor es indeterminado. Entonces, cada compilador es libre de comportarse como quiera. Por ejemplo, en Microsoft Visual C++, en Debug modo, el área de memoria asignada por malloc() está todo listo para 0xCDCDCDCD y cuando en Release modo es aleatorio. En las versiones modernas de GCC, se establece en 0x000000 si no habilita las optimizaciones de código y, de lo contrario, en aleatorio. No sé acerca de otros compiladores, pero entiendes la idea.

  • ¿Puedes dar más detalles? “En las versiones modernas de GCC, se establece en 0x000000 si no habilita las optimizaciones de código y, de lo contrario, es aleatorio”.? Posiblemente incluir una referencia?

    – SS Ana

    29 sep 2019 a las 20:32

  • El último párrafo no es correcto. El simple uso de un valor indeterminado no conduce necesariamente a un comportamiento indefinido. Sin embargo, puede ser muy errático. Se convierte en un comportamiento indefinido si lo pasa a una función de biblioteca.

    – Antti Haapala — Слава Україні

    29/09/2019 a las 19:00

avatar de usuario
trucos

malloc no debe inicializar la memoria asignada a cero.

Memoria asignada por malloc no está inicializado. El valor en estas ubicaciones es indeterminado. En este caso, acceder a esa memoria puede resultar en un comportamiento indefinido si el valor en esa ubicación debe ser una representación de captura para el tipo.

n1570-§6.2.6.1 (p5):

Ciertas representaciones de objetos no necesitan representar un valor del tipo de objeto. Si el valor almacenado de un objeto tiene una representación de este tipo y lo lee una expresión lvalue que no tiene tipo de carácter, el comportamiento no está definido. […]

y la nota al pie dice:

Por lo tanto, una variable automática se puede inicializar en una representación de trampa sin causar un comportamiento indefinido, pero el valor de la variable no se puede usar hasta que se almacene un valor adecuado en ella.

No se puede esperar nada bueno si el comportamiento no está definido. Puede o no obtener el resultado esperado.

void *malloc(size_t size) se supone que debe reservar la cantidad especificada de espacio. Eso es todo. No hay garantía de lo que estará presente en ese espacio.

Citado de las páginas man:

Él malloc() La función asigna bytes de tamaño y devuelve un puntero a la memoria asignada. La memoria no está inicializada. Si size es 0, entonces malloc() devuelve NULL o un valor de puntero único que luego se puede pasar con éxito a free().

Aparte de calloc() puedes usar el memset() para poner a cero un bloque de memoria.

avatar de usuario
kalaiamuthan manisekar

Los ceros se asignan al contenido de la página por primera vez en el kernel de Linux.

El siguiente programa explica la diferencia de inicialización de memoria en malloc y calloc:

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

#define SIZE 5

int main(void) {
    int *mal = (int*)malloc(SIZE*sizeof(int));
    int *cal = (int*)calloc(SIZE, sizeof(int));

    mal[4] = cal[4] = 100;

    free(mal); free(cal);

    mal = (int*)malloc(SIZE*sizeof(int));
    cal = (int*)calloc(SIZE, sizeof(int));

    for(int i=0; i<SIZE; i++) {
        printf("mall[%d] = %d\n", i, mal[i]);
    }
    for(int i=0; i<SIZE; i++) {
        printf("call[%d] = %d\n", i, cal[i]);
    }
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad