0

I currently studying C and one of my practice is to create a linked list in C.

typedef struct deck
{
    int index;
    struct deck *next;
} decks;

My question is that why can't I create a new linked list as follows:(index, card after "=" is defined as variables)

decks* head = malloc(sizeof(decks));
decks* ptr = head;
for(int i = 0; i < 10; i++) {
  ptr -> index = i;
  ptr = ptr -> next;
  ptr = malloc(sizeof(decks));
}

Appreciate so much!

5
  • Because ptr->next is uninitialized and certainly not pointing to an existing memory block. Otherwise you wouldn't need the first malloc either. Commented Mar 12, 2019 at 0:50
  • what about now? @AnttiHaapala Commented Mar 12, 2019 at 0:53
  • so yes, now you'd at least have 11 objects, with 10 of them containing a number and none of them linked to the following, and 9 objects leaked. There is one shortest correct way to do this, then several longer ways to do a linked list and many incorrect ways to do a linked list and even more ways to try to do a linked list and fail at that... there are already dozens of QA existing on how to do it correctly... Commented Mar 12, 2019 at 0:55
  • @AnttiHaapala Why these are leaked? As I have putted variable "head" and only move pointers Commented Mar 12, 2019 at 0:57
  • Please avoid modifying your question. It creates a moving target and makes all previous comments and answers useless. Commented Mar 12, 2019 at 7:00

1 Answer 1

3

Protip on debugging pointers

Draw pictures. Make a box for each instance and an arrow from each non-null pointer. ALWAYS follow the rules listed below. Assuming all memory management is done with malloc and free there are NO exceptions to these rules.

  1. Every time and only when you do a malloc you should draw a new box.
  2. Every time and only when you use free you should remove (or just cross it over with an X or something) a box.
  3. Every time you use free, remove all arrows from that box.
  4. Every time you assign a pointer to a value, null or non-null, remove the old arrow if it exists.
  5. Every time and only when you assign a pointer to a non-null value, draw an arrow.

Note: For a typical call to malloc, you would use both rule 1, 4 and 5. Using malloc without taking care of the return pointer means leaking memory.

Note2: Important! You should NOT remove an arrow TO the box you're deallocating when you use free. Only do that when you specifically assign a pointer to null. In the same way, do NOT remove a box when you assign a pointer to null.

Note3: Important! If you free a box, rule 3 says that you should remove all arrows from that box. Do NOT remove any boxes the arrows are pointing to.

Your question

Consider this:

ptr = ptr -> next;
ptr = malloc(sizeof(decks));

The first line has no effect whatsoever, since you are immediately reassigning ptr. You need something like this:

ptr -> next = malloc(sizeof(decks));
ptr = ptr -> next;

Other remarks

I would recommend using sizeof on the variable rather than the type, like this: ptr->next = malloc(sizeof *(ptr->next)) This is a good habit in general. Take this code:

int *x;
x = malloc(sizeof(int));

Now consider if you want to change the type of the variable x. You would need to change the argument to sizeof in EVERY call to malloc. Using x = malloc(sizeof *x) completely removes this problem.

Sign up to request clarification or add additional context in comments.

2 Comments

Appreciate a lot!
However what can I do if there are two types in the struct type not only integers?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.