Programación C: malloc() dentro de otra función

Resuelto HaggarTheHorrible asked hace 14 años • 9 respuestas

Necesito ayuda con malloc() otra función interna .

Estoy pasando un puntero y un tamaño a la función desde mi main()y me gustaría asignar memoria para ese puntero dinámicamente usando malloc()desde dentro esa función llamada, pero lo que veo es que... la memoria, que se está asignando, es para el puntero declarado dentro de mi función llamada y no para el puntero que está dentro del archivo main().

¿Cómo debo pasar un puntero a una función y asignar memoria para el puntero pasado desde dentro de la función llamada ?


He escrito el siguiente código y obtengo el resultado como se muestra a continuación.

FUENTE:

int main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(input_image, bmp_image_size)==NULL)
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     
   return 0;
}

signed char alloc_pixels(unsigned char *ptr, unsigned int size)
{
    signed char status = NO_ERROR;
    ptr = NULL;

    ptr = (unsigned char*)malloc(size);

    if(ptr== NULL)
    {
        status = ERROR;
        free(ptr);
        printf("\nERROR: Memory allocation did not complete successfully!");
    }

    printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));

    return status;
}

SALIDA DEL PROGRAMA:

Point1: Memory allocated ptr: 262144 bytes
Point2: Memory allocated input_image: 0 bytes
HaggarTheHorrible avatar May 15 '10 05:05 HaggarTheHorrible
Aceptado

¿Cómo debo pasar un puntero a una función y asignar memoria para el puntero pasado desde dentro de la función llamada?

Pregúntate esto: si tuvieras que escribir una función que tuviera que devolver un int, ¿cómo lo harías?

O lo devolverías directamente:

int foo(void)
{
    return 42;
}

o devolverlo a través de un parámetro de salida agregando un nivel de direccionamiento indirecto (es decir, usando en int*lugar de int):

void foo(int* out)
{
    assert(out != NULL);
    *out = 42;
}

Entonces, cuando devuelves un tipo de puntero ( T*), es lo mismo: o devuelves el tipo de puntero directamente:

T* foo(void)
{
    T* p = malloc(...);
    return p;
}

o agregas un nivel de direccionamiento indirecto:

void foo(T** out)
{
    assert(out != NULL);
    *out = malloc(...);
}
jamesdlin avatar May 14 '2010 23:05 jamesdlin

Debe pasar un puntero a un puntero como parámetro de su función.

int main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size) == NO_ERROR)
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     
   return 0;
}

signed char alloc_pixels(unsigned char **ptr, unsigned int size) 
{ 
    signed char status = NO_ERROR; 
    *ptr = NULL; 

    *ptr = (unsigned char*)malloc(size); 

    if(*ptr== NULL) 
    {
        status = ERROR; 
        free(*ptr);      /* this line is completely redundant */
        printf("\nERROR: Memory allocation did not complete successfully!"); 
    } 

    printf("\nPoint1: Memory allocated: %d bytes",_msize(*ptr)); 

    return status; 
} 
Mark Ransom avatar May 14 '2010 22:05 Mark Ransom

Si desea que su función modifique el puntero en sí, deberá pasarlo como un puntero a un puntero. Aquí hay un ejemplo simplificado:

void allocate_memory(char **ptr, size_t size) {
    void *memory = malloc(size);
    if (memory == NULL) {
        // ...error handling (btw, there's no need to call free() on a null pointer. It doesn't do anything.)
    }

    *ptr = (char *)memory;
}

int main() {
   char *data;
   allocate_memory(&data, 16);
}
Matti Virkkunen avatar May 14 '2010 22:05 Matti Virkkunen

Debe pasar el puntero por referencia , no por copia , el parámetro en la función alloc_pixelsrequiere el signo & para devolver la dirección del puntero, es decir, llamar por referencia en C.

principal()
{
   carácter sin firmar *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size)==NULL)
     printf("\nPunto2: Memoria asignada: %d bytes",_msize(input_image));
   demás
     printf("\nPunto3: Memoria no asignada");     

}

char firmado alloc_pixels (char sin firmar **ptr, tamaño int sin firmar)
{
    estado del carácter firmado = NO_ERROR;
    *ptr = NULO;

    *ptr = (carácter sin firmar*)malloc(tamaño);

    si((*ptr) == NULL)
    {
        estado = ERROR;
        /* libre(ptr);
        printf("\nERROR: ¡La asignación de memoria no se completó correctamente!"); */
    }

    printf("\nPunto1: Memoria asignada: %d bytes",_msize(*ptr));

    estado de retorno;
}

He comentado las dos líneas free(ptr)y "ERROR: ..." dentro de la alloc_pixelsfunción porque resulta confuso. No necesita freeun puntero si falla la asignación de memoria.

Editar: Después de mirar el enlace msdn proporcionado por OP, una sugerencia, el ejemplo de código es el mismo que antes en mi respuesta... pero... cambie el especificador de formato %upara el size_ttipo, en la printf(...)llamada en main().

principal()
{
   carácter sin firmar *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size)==NULL)
     printf("\nPunto2: Memoria asignada: %u bytes",_msize(input_image));
   demás
     printf("\nPunto3: Memoria no asignada");     

}
t0mm13b avatar May 14 '2010 23:05 t0mm13b