C Programming: malloc() inside another function
Solution 1:
How should I pass a pointer to a function and allocate memory for the passed pointer from inside the called function?
Ask yourself this: if you had to write a function that had to return an int
, how would you do it?
You'd either return it directly:
int foo(void)
{
return 42;
}
or return it through an output parameter by adding a level of indirection (i.e., using an int*
instead of int
):
void foo(int* out)
{
assert(out != NULL);
*out = 42;
}
So when you're returning a pointer type (T*
), it's the same thing: you either return the pointer type directly:
T* foo(void)
{
T* p = malloc(...);
return p;
}
or you add one level of indirection:
void foo(T** out)
{
assert(out != NULL);
*out = malloc(...);
}
Solution 2:
You need to pass a pointer to a pointer as the parameter to your function.
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;
}
Solution 3:
If you want your function to modify the pointer itself, you'll need to pass it as a pointer to a pointer. Here's a simplified example:
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);
}
Solution 4:
You need to pass the pointer by reference, not by copy, the parameter in the function alloc_pixels
requires the ampersand & to pass back out the address of the pointer - that is call by reference in C speak.
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"); } 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; }
I have commented out the two lines free(ptr)
and "ERROR: ..." within the alloc_pixels
function as that is confusing. You do not need to free
a pointer if the memory allocation failed.
Edit: After looking at the msdn link supplied by OP, a suggestion, the code sample is the same as earlier in my answer.... but...change the format specifier to %u
for the size_t
type, in the printf(...)
call in main()
.
main() { unsigned char *input_image; unsigned int bmp_image_size = 262144; if(alloc_pixels(&input_image, bmp_image_size)==NULL) printf("\nPoint2: Memory allocated: %u bytes",_msize(input_image)); else printf("\nPoint3: Memory not allocated"); }