C Programming: malloc() inside another function

后端 未结 9 1071
暖寄归人
暖寄归人 2020-11-22 06:47

I need help with malloc() inside another function.

I\'m passing a pointer and size to the fu

相关标签:
9条回答
  • 2020-11-22 07:02

    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(...);
    }
    
    0 讨论(0)
  • 2020-11-22 07:02

    In your initial code , when you were passing input_image to the function alloc_pixels, compiler was creating a copy of it (i.e. ptr) and storing the value on the stack. You assign the value returned by malloc to ptr. This value is lost once the function returns to main and the stack unwinds. So, the memory is still allocated on heap but the memory location was never stored in (or assigned to )input_image, hence the issue.

    You can change the signature of the function alloc_pixels which would be simpler to understand, and you won't require the additional 'status' variable as well.

    unsigned char *alloc_pixels(unsigned int size)
    {
        unsigned char *ptr = NULL;
        ptr = (unsigned char *)malloc(size);
        if (ptr != NULL)
           printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));
        return ptr;
    }
    

    You can call the above function in main :

    int main()
    {
       unsigned char *input_image;
       unsigned int bmp_image_size = 262144;
    
       if((input_image = alloc_pixels(bmp_image_size))==NULL)
           printf("\nPoint3: Memory not allocated");    
       else
         printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image)); 
       return 0;
    
    }
    
    0 讨论(0)
  • 2020-11-22 07:03

    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");     
    
    }
    
    0 讨论(0)
  • 2020-11-22 07:03

    Parameters' assignment will work only if you set the value to its address.

    There are 2 points that you should know before you attempt to solve this problem:
    1. C Function: All the parameters you passed to the function will be a copy in the function.

    That means every assignment that you've made in the function will not affect the variables outside the function, you're working on the copy actually:

    int i = 1;
    fun(i);
    printf("%d\n", i);
    //no matter what kind of changes you've made to i in fun, i's value will be 1
    

    So, if you want to change i in the function, you need to know the difference between the thing and its copy:

    The copy shared the value with the thing, but not the address.

    And that's their only difference.

    So the only way to change i in the function is using the address of i.

    For example, there's a new function fun_addr:

    void fun_addr(int *i) {
        *i = some_value;
    }
    

    In this way, you could change i's value.

    1. malloc:

    The key point in the fun_addr function is, you've passed a address to the function. And you could change the value stored in that address.

    What will malloc do?

    malloc will allocate a new memory space, and return the pointer pointed to that address back.

    Look at this instruction:

    int *array = (int*) malloc(sizeof(int) * SIZE);
    

    What you are doing is let array's value equals to the address returned by malloc.

    See? This is the same question, permanently assigning value to the parameter passed to the function. At this point, the value is address.

    Now, assign the address(returned by malloc) to the address(stores the old address).

    So the code should be:

    void fun_addr_addr(int **p) {
        *p = (int*) malloc(sizeof(int) * SIZE);
    }
    

    This one will work.

    0 讨论(0)
  • 2020-11-22 07:04

    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; 
    } 
    
    0 讨论(0)
  • 2020-11-22 07:06

    This does not make sense :

    if(alloc_pixels(input_image, bmp_image_size)==NULL) 
    

    alloc_pixels returns a signed char (ERROR or NO_ERROR) and you compare it to NULL (which is supposed to be used for pointers).

    If you want input_image to be changed, you need to pass a pointer to it to alloc_pixels. alloc_pixels signature would be the following:

    signed char alloc_pixels(unsigned char **ptr, unsigned int size)
    

    You would call it like this:

    alloc_pixels(&input_image, bmp_image_size);
    

    And the memory allocation

    *ptr = malloc(size);
    
    0 讨论(0)
提交回复
热议问题