0

I am implementing the doubly linked list, in functions create_head_node, insert_head, insert_tail i have to copy the array name to node. Then I use function strcpy to copy it but I got segmentation fault error. I reimplement function strcpy by cpystr then I got segmentation fault error at dest[i]=source[i];. Can anybody explain to me why it is wrong and how to fix it. thanks for yor help.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct linked_list
{
    char name[30];
    float point;
    struct linked_list *p_node;
    struct linked_list *n_node;
}node;

node *create_head_node(node *,char *, float);
node *insert_head(node *, char*, float);
void insert_tail(node *, char*, float);
node *insert_after(node *, char*, float, int);
int count_node(node *);
void print_list(node *);
void cpystr(char*, char*);

int main(){
    node *head=(node*)malloc(sizeof(node));
    head=create_head_node(head, "asd fgh", 10);
    head=insert_head(head, "abc def", 9.8);
    insert_tail(head, "qwe rty", 8.98);
    head=insert_after(head, "ui op", 8.7568, 1);
    print_list(head);
    free(head);
    return 0;
}
node *create_head_node(node *head, char name[30], float point){
    cpystr(head->name, name);
    head->point=point;
    head->p_node=NULL;
    head->n_node=NULL;
    return head;
}
node *insert_head(node *head, char name[30], float point){
    node *temp=(node*)malloc(sizeof(node));
    cpystr(temp->name, name);
    temp->point=point;
    temp->p_node=NULL;
    temp->n_node=head;
    head->p_node=temp;
    head=temp;
    return head;
}
void insert_tail(node *head, char name[30], float point){
    node *p=head;
    node *temp=(node*)malloc(sizeof(node));
    cpystr(temp->name, name);
    temp->point=point;
    temp->n_node=NULL;
    while (p!=NULL)
    {
        p=p->n_node;
    }
    p->n_node=temp;
    temp->p_node=p;
}
node *insert_after(node *head, char name[30], float point, int index){
    int count=count_node(head);
    while (index>count)
    {
        printf("choose %d positions to add. choose again: ", count); scanf("%d", index);
    }
    if(index==0) head=insert_head(head, name, point);
    else if(index==count) insert_tail(head, name, point);
    else{
        node *p=head;
        for (int i = 0; i < index-1; i++)
        {
            p=p->n_node;
        }
        node *temp=(node*)malloc(sizeof(node));
        temp->n_node=p->n_node;
        p->n_node->p_node=temp;
        p->n_node=temp;
        temp->p_node=p;
    }
    return head;
}
int count_node(node *head){
    node *p=head;
    int count=0;
    while (p!=NULL)
    {
        count++;
        p=p->n_node;
    }
    free(p);
    return count;
}
void print_list(node *head){
    node *p=head;
    while (p!=NULL)
    {
        printf("%s%10f", p->name, p->point);
        p=p->n_node;
    }
}
void cpystr(char* dest, char* source){
    int i=0;
    while (source[i]!='\0')
    {
        dest[i]=source[i];
        i++;
    }
    *dest='\0';
}
11
  • 1
    node *head; head=create_head_node(head, "viet anh", 10); The head variable is uninitialised but it is dereferenced inside create_head_node. That is undefined behaviour and often (but not always) results in seg faults. Commented Jan 1, 2020 at 5:43
  • where does the head be dereferenced inside create_head_node. Commented Jan 1, 2020 at 5:51
  • and why debugger says seg faults in cpystr function? @kaylum Commented Jan 1, 2020 at 5:52
  • 1
    head->name, head->point, head->p_node, head->n_node. Anything with head-> is a dereference of that pointer. Commented Jan 1, 2020 at 5:52
  • 1
    As soon as undefined behaviour is triggered we can't have any expectation of what the behaviour will be. So a seg fault (or any other behaviour) may happen at any point from where the undefined behaviour first occurs. Commented Jan 1, 2020 at 5:55

2 Answers 2

1

Let's think about how pointers work in general. Pointers are variables whose value contain address of another variable. Thus, pointer must be initialized aka "assigned address of variable it should point to", before you can work with them. Now, when you do node* head. head has not been initialized yet, you must allocate memory for head and associate it's address with head, like this:

    node *head = (node*)malloc( sizeof(node) );

Now you can access members of head like this:

     head->point = 0.01;

Similarly, strcpy will work like this:

     const char *dummy = "Sample";
     strcpy(head->name , dummy);

Please note that strcpy doesn't check for destination's size. Thus, if destination pointer is not large enough to receive the "copy", Undefined behavior may happen and often but not always result in Segmentation fault.

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

Comments

0

regarding:

node *temp=(node*)malloc(sizeof(node));
cpystr(temp->name, name);

and

node *create_head_node(node *head, char name[30], float point){
cpystr(head->name, name);

and similar statements:

best to check (via strlen( name ) that the length is <= 29.

Then use: strncpy( head->name, name, sizeof( node.name )); To assure the name field in the struct is not overrun

Comments

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.