When to malloc for structs and "create" functions in C

Consider a structure, say a List, and a function to return a new list called ListCreate (). ListCreate () takes an object pointer as a parameter, which is an attribute for the list.

Now, as I understand it, the heap memory allocation should be handled by the caller.

Initially, my ListCreate () allocated memory for a new List object that was to be returned and returned a pointer to that List object. This didn't seem to cause any problems, but I understand that it makes sense to get this person to take care of it.

What confuses me is that if I create a List object like this:

List* ListCreate(*foo fum) {
    struct List ls;
    ls.foo = fum;
    ls.data = 0;

    return &ls;
}

      

... then the attributes List (ls.foo) only exist locally for that function. So when I go back to the List pointer in main (), which allocated its own memory for the List object, I realize that ls.foo, ls.data (and any other potential attributes) and & ls are no longer meaningful

One possible solution I think of is that ListCreate () also allocates memory for the attributes of the List object on the heap, and then has its own additional handle to the ListDestroy () function freeing that memory, but then I assume that is means that all of the attributes of the List object must actually be pointers with space allocated for what they point to.

I don't know if this is generally accepted - if my understanding is correct, how is this case usually handled?

+3


source to share


2 answers


Always create parallel functions create

and destroy

(even if destroy

it's just a call free

) and usually avoid functions that directly access its members (make them opaque if possible).



List *ListCreate(Foo *arg) { List *rv = calloc(1, sizeof(List)); rv.arg = arg; return rv; }
void ListDestroy(List *lst) { free(lst); }

      

+1


source


Which solution you suggested is the usual way. In the caller function, do:

struct List ls;

      



Then in the called function:

int ListCreate(*foo fum, struct List *ls) {

    ls->foo = fum;
    ls->data = 0;

    return 0;
}

      

0


source







All Articles