Search code examples
cmemory-managementdynamic-memory-allocationcompound-literals

Is it safe to return a pointer to a compound literal declared within a function or should you use malloc?


Is it safe to return the pointer to a compound literal from a function?

I know the local variables of a function get deallocated after the function returns and that malloc'd memory is an exception to that. However, the compiler isn't giving any warning when I try to return the pointer to a compound literal. Does this mean it is safe to do so?

I compiled using gcc -Wall -o test test.c

The following code compiled without any warnings and outputs 20

#include <stdio.h>

struct test {
    int item;
    struct test *next;
} struct_1 = { .item = 10, .next=NULL };

struct test * returnStruct(){
    struct test * structPointer = (& ((struct test) { .item = 20, .next = NULL }));
    return(structPointer);
}

int main(){
    struct_1.next = returnStruct();
    printf("%d", (struct_1.next)->item);
    return(0);
}

but this code causes a warning

#include <stdio.h>

int * testr(){
    int i = 568;
    return(&i);
}

int main(){
    printf("%d", *testr());
    return(0);
}
warning: address of stack memory associated with local variable 'i' returned [-Wreturn-stack-address]
        return(&i);
                ^
1 warning generated.

Also, if compound literals don't get deallocated after the function returns, does that mean I need to call free on all compound literals in a function?


Solution

  • Is it safe to return the pointer to a compound literal from a function?

    No. Compound literals have the same storage duration as the block they were declared in. So in case they were declared inside a function, they have automatic storage duration and you shouldn't return them for the same reason as why you shouldn't return a pointer to any other local variable.


    The following code compiled without any warnings

    gcc has broken diagnostics, they cannot be trusted. With -Wall -O3 I get this warning:

    warning: function returns address of local variable [-Wreturn-local-addr]
    return(structPointer);

    Without -O3 I do not. Yet another gcc bug. Seems it has been around forever too.


    As for how to solve it, perhaps in this case simply return the struct by value. This is usually not a good idea because structs are often large, but it works just like memcpy.