# What happens when you dereference a pointer to a struct

Emphasis on the example below:  
listint\_t is a struct

```c
listint_t *node;
node = malloc(sizeof(*node));
```

Now, let's consider the following line from the code:

```c
listint_t *node;
```

This line declares a pointer variable named `node` of type `listint_t*`, which means it is a pointer to a `listint_t` struct.

When we dereference `node` using the `*` operator (`*node`), we get the actual object it points to. In this case, `node` points to a `listint_t` struct, so `*node` represents an instance of the `listint_t` struct.

Therefore, when we use `sizeof(*node)`, it calculates the size of the `listint_t` struct, which is the object type that `node` points to.

### Accessing elements in a struct

I used to think just using '\*' is enough to access a struct, but using '\*' only accesses the object itself, you to need to use dot notation or arrow operator to access the elements.

```c
typedef struct listint_s
{
    const int n;
    struct listint_s *prev;
    struct listint_s *next;
} listint_t;
```

To create an instance of the `listint_t` struct, you need to allocate memory for it using `malloc` or a similar memory allocation function. The line `listint_t *node;` declares a pointer variable named `node` of type `listint_t*`, which can hold the memory address of a `listint_t` struct.

To access the members of the `listint_t` struct through the `node` pointer, you need to dereference it using the `*` operator. The expression `*node` dereferences the pointer and gives you the actual object it points to, which is an instance of the `listint_t` struct.

Here's an example to illustrate the concept:  
Using dot notation(member access)

```c
listint_t *node = malloc(sizeof(listint_t));  // Allocate memory for a listint_t struct
(*node).n = 42;                               // Access and assign a value to the n member
(*node).prev = NULL;                          // Access and assign a value to the prev member
(*node).next = NULL;                          // Access and assign a value to the next member
```

Alternatively, you can use the **arrow operator** (`->`) as a shorthand notation to access the members of a struct through a pointer. The arrow operator combines the dereference and member access operations.

Here's an equivalent code snippet using the arrow operator:

```c
listint_t *node = malloc(sizeof(listint_t));  // Allocate memory for a listint_t struct
node->n = 42;                                 // Access and assign a value to the n member
node->prev = NULL;                            // Access and assign a value to the prev member
node->next = NULL;                            // Access and assign a value to the next member
```

To summarize, dereferencing the `node` pointer using `*node` gives you the actual object it points to, which is an instance of the `listint_t` struct. You can then access the members of the struct using either the dot operator (`.`) or the arrow operator (`->`).

### sizeof(node)

If you modify the code to allocate memory without dereferencing the `node` pointer, like this: `node = malloc(sizeof(node))`, it would not work as expected.

In this case, `sizeof(node)` would give you the size of the pointer `node` itself, not the size of the `listint_t` struct. It would allocate memory only for the size of the pointer, which is typically 4 or 8 bytes (depending on the architecture). This would lead to incorrect memory allocation and potential undefined behavior when accessing the struct members.

To allocate memory correctly for a `listint_t` struct, you should use `sizeof(listint_t)` or `sizeof(*node)` in the `malloc` function. Here's the correct allocation:

```c
node = malloc(sizeof(listint_t));
```

or

```c
node = malloc(sizeof(*node));
```

Both expressions ensure that you allocate memory for the size of the `listint_t` struct, which is the appropriate size required to store the members (`n`, `prev`, `next`) of the struct.

Always make sure to use the correct size when allocating memory to ensure proper memory allocation and avoid potential issues with accessing the struct members.
