Programación C: malloc() dentro de otra función
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
¿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(...);
}
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;
}
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);
}
Debe pasar el puntero por referencia , no por copia , el parámetro en la función alloc_pixels
requiere 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_pixels
función porque resulta confuso. No necesita free
un 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 %u
para el size_t
tipo, 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"); }