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.
- I call the
InitList
with address of list typed List. - I expected that list would be initialized because I gave argument with address.
- But when I printed the value of
count
oflist
, it was garbage value. (when I printed inInitList
, that was 0) - So
count
was not zero whilehead
andtail
of list wasNULL
(found throughassert
), 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;