Initializing a pointer in a function

Both are wrong:

Here you return the pointer to a local variable, but once the function newEmptyList is terminated, list no longer exists:

struct MyList *newEmptyList() {
    struct MyList list;
    list.head = NULL;
    return &list;
}

This is wrong because list (which is a pointer) points nowhere and therefore you cannot dereference it like here: list->head = NULL;

struct MyList *newEmptyList() {
    struct MyList *list;
    list->head = NULL;
    return list;
}

You probably want this:

struct MyList *newEmptyList() {
    struct MyList *list = malloc(sizeof(*list));
    list->head = NULL;
    return list;
}

malloc allocates memory for your list pointer. After the call to malloc, list points to some valid memory.


Both cause undefined-behaviour:

struct MyList *newEmptyList() {
    struct MyList list;
    list.head = NULL;
    return &list;
}
struct MyList *newEmptyList() {
    struct MyList *list;
    list->head = NULL;
    return list;
}

In the first one, you are returning the address of a local variable which is on the stack. As when the function returns, accessing the values previously on that stack is undefined behavior. It doesn't cause undefined behavior until you dereference the pointer returned.

In the second one:

  1. Pointers not assigned to a memory address is dangerous to use. Causes undefined behavior
  2. list->head dereferences list which causes undefined behavior straight away, as the pointer doesn't point to a usable memory address, and you are trying to write to that memory address...

The correct way to do this is:

struct MyList *newEmptyList() {
    struct MyList *list = malloc(sizeof(struct MyList));
    list->head = NULL;
    return list;
}

malloc() allocates memory on the heap and returns the memory address of the start of the allocated memory.

Pointers

Pointers in C are basically variables that hold the address of other variables.