Home > Back-end >  pointer problem of circuit doubly LinkedList in C
pointer problem of circuit doubly LinkedList in C

Time:12-18

Error was happend in main at bottom.

Add Node - data : 1
Segmentation fault (core dumped)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct Node
{
    int data;
    struct Node* prev;
    struct Node* next;
}Node;

typedef struct List
{
    Node* head;
    Node* tail;
    int count;
}List;
void InitList(List *list)
{
    (list) = (List*)malloc(sizeof(List));
    (list) -> head = NULL;
    (list) -> tail = NULL;
    (list) -> count = 0;
}
Node* CreateNode(int data)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node -> data = data;
    node -> prev = NULL;
    node -> next = NULL;
    return node;
}
void AddNode(List *list, Node* node)
{
    if (!(list) || !node) return;
    printf("Add Node - data : %d\n", node -> data);

    if ((list) -> count == 0)
    {
        (list) -> head = (list) -> tail = node;
        node -> next = node -> prev = node;
    }
    else
    {
        node -> prev = (list) -> tail;
        node -> next = node -> prev = node;
        
        (list) -> tail -> next = node;
        (list) -> head -> prev = node;
        (list) -> tail = node;
    }

    (list) -> count  ;
}
int main()
{
    List list;
    InitList(&list);
    for (int i = 1; i < 5; i  ) 
        AddNode(&list, CreateNode(i));

    return 0;
}

This is a code about circuit doubly LinkedList in C. There was exist original code and I revised that to know why at original multiple pointer was used. Error happened directly when AddNode(&list, CreateNode(i) was called in main.

(this was the site of the original code but not english) (https://huiyu.tistory.com/entry/자료구조-동적할당을-이용한-연결-리스트Linked-List-구현)

I expected that It'll be working because in main, I declared List list and then call InitList(&list). I thought it was call-by-reference but it didn't maybe.

I tried some tests, then I found tsomething.

  1. I call the InitList with address of list typed List.
  2. I expected that list would be initialized because I gave argument with address.
  3. But when I printed the value of count of list, it was garbage value. (when I printed in InitList, that was 0)
  4. So count was not zero while head and tail of list was NULL(found through assert), then Error happened.

I cannot understand why it was not call-by-reference, and why multiple pointers is needed.

CodePudding user response:

Remember that arguments to functions are passed by value. That means the values in the call is copied into the functions local argument variables. All the function have is a copy, which is independent of the original variable or value from the call. That means

(list) = (List*)malloc(sizeof(List));

in your InitList will simply not work, you only modify the local list variable. The original value &list from the main function will not be modified. And in fact it cant.

This means that the List structure object you initialize in the InitList function, is not the same as the one in the main function. The List structure object in the main function will remain uninitialized.

It seems you have heard that emulating pass by reference works by passing pointers to variables. But you miss an important point: The pointer itself will still be passed by value.

The simple solution to your problem is to simply drop that assignment from the InitList function:

void InitList(List *list)
{
    // list is already pointing to a properly allocated List structure
    (list) -> head = NULL;
    (list) -> tail = NULL;
    (list) -> count = 0;
}

Other alternatives is to change list in the main function to a pointer, and pass a pointer to that pointer, which means that InitList must take a List **list argument. Or you define list as a normal local variable, do the allocation, and then return the pointer.

CodePudding user response:

When you write List list; => memory is already allocated to list object now when you do malloc again inside the initlist() function then you point the pointer to a new memory location and hence this pointer which was earlier pointing to the location of list object is now pointing to some other address location. So all the changes that you made to this pointer in initlist functions are reflected to the struct object stored at some new address location (other than the list object).

Solution: Same as mentioned in other answers i.e. removing malloc line inside initlist function.

CodePudding user response:

Or you can leave mallock() inside InitList function, but then You just need to define 'list' variable as a pointer to List structure in main() function:

List *list = NULL;
  • Related