Search code examples
cmallocheap-memorystorage-duration

Returning a pointer on the heap and the consequential behaviour


Imagine I have the below scenario: Now if I allocate a pointer inside a function on the heap, and return this pointer back to the main program, is the memory still on the heap, and do I have to free it?

static char* assignValue()
{
  char* value = (char*)malloc(sizeof(char*) * 1024);
  strcpy(value, "random");

  return value;
}

int main(void)
{
  char* mainValue = assignValue(); // is the memory still on the heap?

  printf("%s", mainValue);

  free(mainValue);  // and, is this also correct?
}

I was wondering how to handle this situation.


Solution

  • In sort :

    Yes.

    In long :

    char* value = (char*)malloc(sizeof(char*) * 1024);
    

    malloc() return a pointer to a memory location. And you store this memory location in value for later usage.

    value is a stack variable where you stock this memory location, and have the same behavior of any stack variable. (in this case value gonna be destroy at the end of the scope)

    The malloc() memory location is in the heap and don't have the stack behavior. But you need to pass this memory location to free().

    If you don't pass this memory location to free(), that create a still reachable leak. If you loss this pointer to memory location somewhere this create a definitely lost or indirectly lost leak.

    char* mainValue = assignValue();
    

    Here you create a new mainValue and you assign this lvalue (left value) with the assignValue() fonction.

    In assignValue() you return the value containing the value malloc() give you (the heap memory location).

    That have for effect to store the value of value in mainValue.

    We can check that with printf("%p") (%p is for pointer argument) :

    #include <stdio.h>
    #include <stdlib.h>
    
    char *
    foo(void)
    {
            char * ptr;
    
            ptr = malloc(1);
            printf("%p\n", ptr);
            return (ptr);
    }
    
    int
    main(void)
    {
            char * my_ptr;
    
            my_ptr = foo();
            printf("%p\n", my_ptr);
            free(my_ptr);
            return (0);
    }
    

    Output :

    ➜  test ./a.out
    0x557cb28e92a0
    0x557cb28e92a0
    

    Here we can see two time the same value. (0x is for hexadecimal value)

    And with that I can safely pass the my_ptr pointer to free().

    You need to be careful with heap memory location pointer. If you give a wrong pointer to free(), that a undefined behavior. And create leak is also not a option.

    You need to be sure you free() everything correctly.

    If you start to do bigger code where error is common, you probably want to use a debugger.

    Richard Stallman’s advice, from personal experience, is to turn to the debugger as soon as you can reproduce the problem. Don’t try to avoid it by using other methods instead— occasionally they are shortcuts, but usually they waste an unbounded amount of time. With the debugger, you will surely find the bug in a reasonable time; overall, you will get your work done faster. The sooner you get serious and start the debugger, the sooner you are likely to find the bug.

    for more info, check the man