0

I have been trying to write a program which inserts a string into the beginning of the linked list, however there has been a slight problem in it. My code is the following.

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

struct node{
    char* data;
    struct node* next;
};



void insIni(struct node** hp, char* x){
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = x;
    tmp->next = *hp;
    *hp = tmp;
}

void printList(struct node* h){
    struct node* tmp = h;
    printf("\nList contents: \n");
    while (tmp != NULL){
        printf("%s,  ", tmp->data );
        tmp = tmp->next;
    }
    printf("\n");
}

int main(int argc, char const *argv[]){

    struct node* head = NULL;  

     char word [256];
     scanf("%s", word);  
    insIni(&head, word);
    scanf("%s", word);  
    insIni(&head, word);
    scanf("%s", word);  
    insIni(&head, word);

    printList(head);

    return 0;
}

After I insert a new string at the beginning of the linked list, the previous elements are also changed to be the same as the string that has just been insterted, how can I change my code so that the previous elements of the linked list stay the same and only the element at the beginning is added?

For example, if I write A B C, the Linked List ends up being printed as C, C, C, instead of C, B, A,.

George Francis
  • 462
  • 2
  • 7
  • 16
  • It works, but `scanf("%s", word);` in main() reads the input into the same character array each time. you could replace `tmp->data = x;` in isnsIni() to `tmp->data = strdup(x);` – wildplasser Oct 08 '16 at 17:17
  • Ok, that change seemd to solve my problem, however when compiling I recieve the following warning: incompatible implicit declaration of built in function 'strdup'. Is this dangerous? And if so how can I remove it? – George Francis Oct 08 '16 at 17:29
  • You need to `#include ` to use strdup() (NOTE: strdup is *slightly* non-standard) – wildplasser Oct 08 '16 at 17:32
  • strdup is POSIX and that is very well a standard – Bodo Thiesen Oct 08 '16 at 23:16

2 Answers2

0

The value you pass to insIni is always the same so all nodes will point to the same. What you need to do is a copy of the data.

E.g.

void insIni(struct node** hp, char* x){
    struct node* tmp = (struct node *)malloc(sizeof(struct node)); 
    tmp->data = strdup(x);
    tmp->next = *hp;
    *hp = tmp;
}

or

char *p = malloc(strlen(x)+1);
strcpy(p, x);
tmp->data = p;
AndersK
  • 35,813
  • 6
  • 60
  • 86
  • The solution with strdup seems to work, thanks! However, when compiling, I receive a warning: incompatible implicit declaration of built in function 'strdup'. Is this dangerous? And if so, how can I remove it? – George Francis Oct 08 '16 at 17:27
  • @GeorgeFrancis you need to include the appropriate header. any function which the C compiler finds that has no prototype is assumed returning int. `#include ` – AndersK Oct 08 '16 at 17:30
0

scanf reads the text into the array word. In the call insIni(&head, word);, you do NOT pass the string but the address of the array word. In insIni in the line tmp->data = x; you copy that address to the element data. But it's still the array word from function main. So next scanf will overwrite the content of that array. The next call to insIni(&head, word); will then assign the same address to the next struct. So, what you actually need is to allocate memory for the string, either prior (or after) the scanf statement or in insIni. Something like char * word; instead of char word [256]; and word = malloc(256); in front of every scanf will do the job. Also, scanf is dangerous because of buffer overflows, so you probably want to read this one: How to prevent scanf causing a buffer overflow in C?

Community
  • 1
  • 1
Bodo Thiesen
  • 2,476
  • 18
  • 32