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");     

}