2009-09-09 7 views
28

¿Por qué se debería usar la función realloc() para cambiar el tamaño de una matriz dinámicamente asignada en lugar de usar la función free() antes de llamar de nuevo a la función malloc()? contra desventajas, etc.)? Es para programación en C, pero no puedo encontrar la etiqueta adecuada para ello. Gracias por adelantado.Diferencias entre utilizar realloc vs. libre -> funciones malloc

+0

¿Por qué necesita memoria si no le importa su contenido? – Philip

Respuesta

20

La ventaja es que realloc preservará el contenido de la memoria. Con + Malloc gratis necesitarías restablecer los datos en la matriz.

+4

que también es la desventaja. Si no está interesado en la preservación de datos, hacer el malloc libre y podría ser más rápido en algunos casos (donde el bloque de memoria debe moverse debido al crecimiento del tamaño) – Toad

+7

Es más rápido volver a colocarlo de nuevo, y puede ser más rápido volver a colocarlo si hay espacio para crecer en su lugar. De lo contrario, se traduce a malloc/copy/free. –

+1

aún ... si no necesita conservar los datos, un malloc gratuito parece más descriptivo de lo que está haciendo. – Toad

6

Bueno, realloc puede cambiar el tamaño del bloque en su lugar, o asignar uno nuevo y copiar tanto como encaje. Por el contrario, malloc y free together solo pueden asignar uno nuevo, y usted debe hacer su propia copia.

Para ser sincero, realloc no tiene tanto uso en estos días porque no funciona bien con C++. Como resultado, los administradores de memoria tienden a no optimizarlo.

+1

Su afirmación con respecto a los administradores de memoria y realloc que no se han optimizado para ello, ¿ha leído algo al respecto? – ArmenB

+0

@ArmenB. No estoy seguro de lo que estaba pensando en 2009, pero desde entonces he visto el código de TCMalloc y no está realmente orientado al cambio de tamaño. –

1

"en lugar de utilizar la función free() antes de llamar a la función malloc() de nuevo"

Si usted libera la matriz existente, que ha perdido todo su contenido, por lo que no se puede "crecer" la matriz en el sentido usual

+0

Estoy seguro de que querían decir que llamarían malloc, copiarían cosas y luego lo liberarían. –

+0

Steven acaba de decir lo que quise decir. – stanigator

3

Tenía un programa que estaba haciendo un montón de llamadas gratuitas() y malloc() para hacer una matriz dinámica, y pensé que optimizaría reutilizando la matriz existente cuando fuera posible. Los puntos de referencia mostraron que realloc() en promedio es más lento que simplemente llamar a free() y malloc(). Supongo que tiene sentido, ya que a veces crecería y quizás requeriría una copia.

11

Sé que esta pregunta es muy antigua (fue respondida en 2009) pero espero que mi respuesta ayude a quienes buscan y se encuentran con esta pregunta (como yo).

Si bien este punto de referencia no es definitivo ya que la gestión de memoria varía en los diferentes sistemas, hoy en día las cosas tienden a ser bastante estandarizado, por lo que estos resultados deben ser seguro para su uso como un punto de referencia (Si usted sabe de un caso de la vida real no es, por favor dime). Estoy usando Windows 7 en un QuadCore Intel Core i3 2310M a 2.10 GHz con 4 GB de RAM. No es el mejor hardware de todos los tiempos, pero es el mejor que tengo ahora.

Lo que hace este índice de referencia es que comienza con una cierta cantidad de memoria (INITIAL_MEMORY) y reasigna repetidas veces en pequeñas cantidades (BYTE_STEP) hasta que asigna/desasigna completamente ALLOCATE_MEMORY. Para esto, intenta 6 enfoques:

  1. Aumento de pérdida de Malloc: libre() y malloc() más memoria.
  2. Disminución de Malloc perdida: libre() y malloc() menos memoria.
  3. Incrementando Malloc: malloc() más memoria, copia datos y memoria anterior() libre.
  4. Disminución de Malloc: malloc() menos memoria, copia datos y memoria anterior() libre.
  5. Aumento de Realloc: realloc() más memoria.
  6. Disminución de Realloc: realloc() menos memoria.

Así, la primera prueba: Comience con 2 MB y asignar ± 1 MB en pasos de 1 KB:

Increasing Lossful Malloc took 3 ms 
Decreasing Lossful Malloc took 5 ms 
Increasing Malloc took 1 265 ms 
Decreasing Malloc took 744 ms 
Increasing Realloc took 316 ms 
Decreasing Realloc took 0 ms 

Como podemos ver, copiar manualmente con el establecimiento de memoria es siempre más lento que realloc, ya que en este escenario Malloc tiene la garantía de asignar nueva memoria y usted está obligado a copiar los datos en cada asignación, lo que nos muestra que realloc está reutilizando la misma dirección y ampliando el tamaño del bloque en algunos casos. Entonces, si desea conservar sus datos, es probable que realloc sea lo que quiere usar. Para simplificar las cosas, no seguiré probando este enfoque malloc sin pérdidas.

Vamos a proceder a la siguiente prueba: inicial de la memoria de 32 MB, la asignación de 16 MB en los pasos 16KB:

Increasing Lossful Malloc took 4 ms 
Decreasing Lossful Malloc took 4 ms 
Increasing Realloc took 21 453 ms 
Decreasing Realloc took 0 ms 

Ahora, podemos ver que el aumento de realloc toma mucho de tiempo en comparación con las otras pruebas. La disminución de realloc ni siquiera ha llegado a 1 ms. Esto muestra que si no quieres conservar tu memoria, debes usar un enfoque libre-> malloc, ¿o no? Mira estos resultados:

Increasing Lossful Malloc took 777 ms 
Decreasing Lossful Malloc took 729 ms 
Decreasing Realloc took 19 ms 

(. Estos resultados eran demasiado cerca, así que se ejecutan varias pruebas y los promediaron)

Definitivamente disminuyendo el tamaño de la memoria es más eficaz cuando se utiliza realloc(). Eso es probablemente porque realloc no necesita buscar un nuevo bloque de memoria, solo usa el anterior y lo reduce. Esta es una gran diferencia en el rendimiento de si está utilizando la asignación en gran medida.

Además, podemos ver que el aumento de malloc es ligeramente más lento que el decreciente, incluso cuando ambos hacen básicamente lo mismo: encontrar un bloque de memoria y asignarlo. Esta diferencia se debe probablemente a que, al buscar bloques más grandes, malloc necesita buscar más tiempo en promedio que cuando busca bloques más pequeños. Por ejemplo, si hay un bloque de 30MB, un malloc que asigna 16MB lo usaría, pero un malloc que asigna 32MB tendría que omitirlo y seguir buscando y utilizando el tiempo de actividad. Esta es probablemente la razón por la que los resultados variaron tanto en mis pruebas.

En conclusión/TLDR:

  1. Si usted necesita para mantener sus datos, utilice realloc(). Es ~ 4 veces más rápido que usar malloc()/free() y copiar sus datos cuando escalando. Al escalar hacia abajo, es 10,000-100,000 veces más rápido. NUNCA copiar cosas manualmente.
  2. Si no necesitan para mantener sus datos, debe utilizar malloc()/libre() para escala hasta (aumento de tamaño de la memoria) pero el uso de realloc() cuando escalar hacia abajo (reducción de tamaño de la memoria)
  3. Si no conoce el tamaño anterior (no sabe si está reduciendo o reduciendo), use malloc()/free(). Al reducir la escala, realloc() es ~ 40 veces más rápido, pero cuando se escala, realloc() es ~ 7600 veces más lento. A menos que su programa haga algunas grandes asignaciones y toneladas de pequeñas desasignaciones (~ 200 veces más desasignaciones que asignaciones, que pueden ser posibles), debe usar malloc()/free().

Aquí es mi fuente de referencia: test.cpp

Ahora, por favor, si hice algo mal o tiene algún comentario, no dude en decirle/corregirme.

Cuestiones relacionadas