¿Diferencia entre malloc y calloc?
¿Cuál es la diferencia entre hacer:
ptr = malloc(MAXELEMS * sizeof(char *));
Y:
ptr = calloc(MAXELEMS, sizeof(char*));
¿ Cuándo es una buena idea utilizar calloc
over malloc
o viceversa?
calloc()
le proporciona un búfer inicializado a cero, mientras que malloc()
deja la memoria sin inicializar.
Para asignaciones grandes, la mayoría de calloc
las implementaciones en los sistemas operativos convencionales obtendrán páginas con puesta a cero conocida del sistema operativo (por ejemplo, a través de POSIX mmap(MAP_ANONYMOUS)
o Windows VirtualAlloc
), por lo que no es necesario escribirlas en el espacio del usuario. Así es como lo normal malloc
también obtiene más páginas del sistema operativo; calloc
simplemente aprovecha la garantía del sistema operativo.
Esto significa que calloc
la memoria aún puede estar "limpia" y asignarse de manera diferida, y la copia en escritura puede asignarse a una página física de ceros compartida en todo el sistema. (Suponiendo un sistema con memoria virtual). Los efectos son visibles con experimentos de rendimiento en Linux , por ejemplo.
Algunos compiladores incluso pueden optimizar malloc + memset(0) en calloc por usted, pero es mejor usar calloc en la fuente si desea poner a cero la memoria. (O si estaba intentando establecer un error previo para evitar errores de página más adelante, esa optimización anulará su intento).
Si nunca va a leer la memoria antes de escribirla, úsela malloc
para que pueda (potencialmente) proporcionarle memoria sucia de su lista interna libre en lugar de obtener nuevas páginas del sistema operativo. (O en lugar de poner a cero un bloque de memoria en la lista libre para una pequeña asignación).
Las implementaciones integradas de calloc
pueden dejarlo calloc
solo con memoria cero si no hay un sistema operativo, o si no es un elegante sistema operativo multiusuario que pone a cero las páginas para detener las fugas de información entre procesos.
En Linux integrado, malloc podría mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS)
, que sólo está habilitado para algunos núcleos integrados porque es inseguro en un sistema multiusuario.
Una diferencia menos conocida es que en los sistemas operativos con asignación de memoria optimista, como Linux, el puntero devuelto malloc
no está respaldado por memoria real hasta que el programa realmente lo toca.
calloc
De hecho, toca la memoria (escribe ceros en ella) y, por lo tanto, estará seguro de que el sistema operativo respalda la asignación con RAM real (o intercambio). Esta es también la razón por la que es más lento que malloc (no sólo tiene que ponerlo a cero, el sistema operativo también debe encontrar un área de memoria adecuada posiblemente intercambiando otros procesos)
Consulte, por ejemplo, esta pregunta SO para obtener más información sobre el comportamiento de malloc