Allow me to expand on my suggestions in post #3:
Code:
/* ... */
struct node {
int x;
struct node *next;
struct node *previous;
};
struct linked_list {
struct node *start;
struct node *tail;
};
struct node *append_node(struct linked_list *list, int value) {
struct node *new_node = malloc(sizeof(*new_node));
if (new_node) {
new_node->x = value;
new_node->next = NULL;
if (list->start) {
new_node->previous = list->tail;
list->tail->next = new_node;
list->tail = new_node;
} else {
new_node->previous = NULL;
list->start = new_node;
list->tail = new_node;
}
}
return new_node;
}
void create_list(struct linked_list *list) {
int val = 0;
printf("We are to create new linked list. Enter number\n");
if (scanf("%d", &val) == 1) {
struct node *temp = append_node(list, val);
if (temp) {
printf("The value is %d\n", temp->x);
} else {
/* Could not append node, so report or otherwise handle the error */
}
} else {
/* Invalid input, so report or otherwise handle the error */
}
}
/* ... */
int main(void) {
struct linked_list list = {NULL};
create_list(&list);
/* ... */
return 0;
}
Doing it this way, you separate the logic of appending a node from the logic of doing interactive I/O and actually building the linked list.
I have taken the liberty of implementing append_node for you as it looks like you did put in effort to think about and implement the logic as per post #1. Notice that:
- Instead of calling malloc in two places like you did, I did it in just one place and did the check for a null pointer before proceeding.
- Instead of setting the new node's value and next pointer in two places like you did, I did it in just one place once it is known that malloc did not return a null pointer.
- Instead of doing a loop to find the tail, I just used the tail pointer.
- Since I separated append_node from create_list, I made it such that create_list (and other functions that might use append_node) can check if append_node succeeded.
Also, while you did correctly fix the malloc call to:
Code:
struct node* new=malloc(sizeof(struct node));
Using this instead:
Code:
struct node *new_node = malloc(sizeof(*new_node));
avoid having to check that you did use the correct type.
By the way, I think that it is conventional to use head and tail rather than start and tail. If you do want to use start, I would expect start and end. (There's also start and stop as well as start and finish, but those probably would be unconventional for linked lists.)