2011-09-28 9 views
20

Duplicar posible:
Why calloc takes two arguments while malloc only one?¿Cómo terminaron malloc y calloc con diferentes firmas?

Hay un montón de los recursos que describen la diferencia de funcionalidad entre malloc y calloc, pero no pueden encontrar fácilmente uno que describe la historia detrás las diferentes firmas de función:

void *calloc(size_t nmemb, size_t size); 
    void *malloc(size_t size); 

Por supuesto, el size en el primero es el tamaño para cada miembro. ¿Tal vez la idea era que los callocs de tamaño de miembro de tamaño múltiple de la página se podían hacer de forma perezosa a través del sistema operativo?

(puedo compensar razones, así como el tipo de al lado -. Respuestas no aceptados sin fuentes citadas :-)

+0

Extremadamente relacionado: http://stackoverflow.com/q/7536413/142019 –

+1

No hay citas, así que solo un comentario: la firma 'calloc' es más útil, ya que una implementación adecuada verifica el desbordamiento al multiplicar, aliviando el llamador de la responsabilidad. Sospecho una de dos explicaciones: (1) 'malloc' fue lo primero, y es solo una cuestión de compatibilidad, (2)' calloc' se espera que sea más lento debido a la puesta a cero, y alguien pensó que el control de multiplicación y desbordamiento en 'malloc' se debe omitir para la velocidad. –

+0

Me resulta extraño que una pregunta se pueda cerrar como un duplicado exacto de una pregunta menos específica sin respuestas satisfactorias (o aceptadas). Me pregunto cómo surgieron las dos firmas históricamente. – cdleary

Respuesta

1

Esto es algo abierto a la interpretación del lenguaje utilizado en la especificación C.

El lenguaje aquí parece muy cuidadosamente elegido - malloc se define en la sección 7.20.3.3 como:

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

principios de un objeto se define en la sección 3.14 como:

región de almacenamiento de datos en el entorno de ejecución, los contenido de las cuales pueden representar valores

calloc por otra parte se define en 7.20.3.1 como:

La función calloc asigna espacio para una matriz de los objetos nmemb, cada uno de cuyo tamaño es el tamaño. El espacio se inicializa a todos los bits cero.

Esto debería hacerlo obvio. La diferencia entre calloc y malloc es que calloc asigna memoria para una matriz de n objetos conceptuales, aunque en la práctica esto no es diferente de una llamada a malloc que asigna espacio para 1 objeto conceptual de tamaño (n * tamaño).

Así que la siguiente pregunta es ... ¿cuál es la necesidad de distinguir entre el espacio para una matriz de objetos y el espacio para un objeto grande?

Desde la perspectiva de los programadores, las dos llamadas a funciones solo piden cosas diferentes. Uno está pidiendo que se le asigne un gran trozo de memoria, y me ocuparé de ello. El otro dice: quiero una serie de n cosas que son de este tamaño, darme algo de memoria que pueda usar para esta matriz y ponerla a cero, porque en la mayoría de las implementaciones puedo hacer buenas suposiciones sobre lo que significa la memoria cero.

El hecho de que esté tratando de usarlo como malloc + zeroing es, al leer la especificación, un malentendido sobre el propósito de la función.

Terminaron con diferentes firmas porque hacen cosas diferentes.


Algunos pensamientos secundarios lindo ... Una implementación de malloc trivial puede parecer:

#define malloc(x) (calloc(1, x)) 

También es divertido tener en cuenta que si mi representación puntero NULL no se pone a cero, entonces no lo hará calloc devuélveme una matriz de punteros NULL. Mejor aún, si diseño una representación entera en la que la memoria cero no es ((int) 0), calloc no me devolverá una matriz de 0.

+0

Así que básicamente está diciendo que 'calloc' devuelve una matriz de objetos inicializados (dado que no se garantiza que todos los bits-cero sean un objeto válido para todos los tipos en todas las implementaciones, es al menos un intento razonable de inicialización), mientras que 'malloc' devuelve la memoria sin inicializar en bruto para un objeto o una matriz? –

+0

En cuanto a sus notas divertidas, en realidad podría diseñar una implementación en la que todos los bits cero sea una representación de trampas de todo tipo, excepto 'char' y' signed/unsigned char', lo que hace que 'calloc' sea casi inútil. Como corolario, 'calloc' es casi inútil en programas estrictamente conformes, y su segundo parámetro es completamente inútil en programas estrictamente conformes ya que los únicos tipos para los que es útil tienen tamaño 1. –

+0

@Steve Jessop: las representaciones de trampas no son un problema mientras como no los evalúa, puede sobrescribirlos muy bien en un programa estrictamente conforme. – caf

Cuestiones relacionadas