¿Diferencia entre malloc y realloc?

4 minutos de lectura

unnamed file 101
profundo

Supongamos que tengo dos ejemplos de código para crear una matriz de enteros de 10 elementos:

int *pi = (int*)0; 
realloc(pi,10);

y el otro es el que se escribe normalmente, es decir:

int *pi;
pi= malloc(10*sizeof(int));

Ahora, mi pregunta es: El primer tipo de cesión es legal pero no se utiliza. ¿Por qué, aunque allí puedo obtener la ubicación de partida de mi elección?
La inicialización de punteros con constantes es legal pero no se usa. ¿Por qué?

  • No debe convertir el valor de retorno de malloc en C.

    – RojoX

    17 de octubre de 2013 a las 8:28

unnamed file 102
Corbin

Cuando NULL esta pasado, realloc es equivalente a malloc. los NULL call puede ser útil si está reubicando en algún tipo de ciclo y no quiere tener un caso especial la primera vez que asigna.


Mientras estamos en eso, las formas bastante estándar de usar malloc y realloc son:

int* p;
p = malloc(10 * sizeof(int)); //Note that there's no cast
//(also, it could just be int* p = malloc(...);)

int* np = realloc(p, 15 * sizeof(int));
//Note that you keep the old pointer -- this is in case the realloc fails

Como un aparte tangencial: la historia es la razón principal por la que ve declaraciones y asignaciones en diferentes líneas. En versiones anteriores de C, las declaraciones tenían que aparecer primero en las funciones. Eso significaba que incluso si su función no usaba una variable hasta las 20 líneas, tenía que declarar en la parte superior.

Dado que normalmente no sabe cuál debe ser el valor de una variable que no se usa para otras 20 líneas, no siempre puede inicializarla en algo significativo y, por lo tanto, se queda con una declaración y sin asignación en la parte superior de su función.

En C99/C11, no tiene que declarar variables en la parte superior de los ámbitos. De hecho, generalmente se sugiere definir las variables lo más cerca posible de su uso.

  • O NULL. Es legal en la medida en que el compilador no arroje un error de compilación.

    –Daniel Fischer

    12 de noviembre de 2012 a las 19:51


  • Pero en el entorno de memoria virtual, mi programa posee toda la memoria.

    – profundo

    12 de noviembre de 2012 a las 19:53

  • @me.deeiip no, esa es una suposición falsa. No puede simplemente usar direcciones de memoria arbitrarias, las direcciones que usa deben serle otorgadas por otras funciones que aseguren que el sistema sepa cómo permitirle usarlas.

    – mah

    12 de noviembre de 2012 a las 19:55


  • @me.deeiip Eso es porque has entrado en el mundo del comportamiento indefinido. Uno de los comportamientos posibles en el comportamiento indefinido es el comportamiento ‘correcto’, pero no está garantizado.

    – Corbin

    12 de noviembre de 2012 a las 20:03


  • @me.deeiip: el comportamiento es indefinido; puede Aparecer estar trabajando normalmente, pero eso es por accidente, no por diseño. El primer argumento a realloc debe ser NULL o el resultado de uno de los *alloc funciones

    – Juan Bode

    12 de noviembre de 2012 a las 20:04


C requiere que el puntero pasado a realloc debe ser un puntero obtenido de malloc, calloc o realloc llamada de función (o un puntero nulo).

  • o calloc o un anterior realloctal vez otros?

    – mah

    12 de noviembre de 2012 a las 19:52

  • @mah Gracias, agregado a mi respuesta.

    – ouah

    12 de noviembre de 2012 a las 19:53

  • @mah de la alloc familia de funciones podría ser la mejor manera de expresarlo.

    – dmckee — gatito ex-moderador

    12 de noviembre de 2012 a las 19:55

  • @dmckee Un comentarista demasiado cauteloso podría haber agregado “[a pointer obtained] de la familia de funciones alloc que aún no ha sido liberada”, pero eso sería redundante: liberar cualquier versión de un puntero hace que todas sus copias sean indeterminadas. Las otras copias, en cierto sentido, ya no existen y, por lo tanto, no se pueden pasar a realloc()o free(). blog.frama-c.com/index.php?post/2012/01/05/Double-free

    – Pascal Cuoq

    12 de noviembre de 2012 a las 20:11

  • ::se tambalea melodramáticamente agarrando el corazón:: ¡Ay de mí! ¡Fuera colgante! ¡Otra vez! ::cae al suelo, canta aria, muere largamente:: @PascalCuoq Tú ganas.

    – dmckee — gatito ex-moderador

    12 de noviembre de 2012 a las 20:17

La primera tarea es no legal, porque el puntero al que pasas realloc() debe haberle sido entregado previamente a través de una asignación de algún tipo. (Además, está ignorando su valor de retorno, ¡algo que nunca debe hacer con las asignaciones!)

malloc() es crear un búfer para algo, de algún tamaño fijo. realloc() es devolver un búfer y obtener otro de algún tamaño (presumiblemente) diferente, y podría devolverle el mismo búfer que estaba usando.

¿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