node pointer of a list wont update - c

I had a problem and I cannot seem to find a solution.I tried to do a simple program that creates a list and prints it in C, but when i tried to run it it looped printing the first value of the list.This is the program if anyone could help plz:
I tried adding parenthesis etc but didn't work.
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo{
int dato;
struct nodo *next;
}nodo_t;
typedef nodo_t *Ptr_nodo;
int main(){
Ptr_nodo testa,temp;
int q;
temp=NULL;
testa=NULL;
temp=malloc(sizeof(nodo_t));
if(temp){
q=0;
while(q!=-1){
printf("Inserire valore: ");
scanf("%d",&q);
if(q!=-1){
temp->dato=q;
temp->next=testa;
testa=temp;
}
}
while(testa!=NULL){
printf("%d",testa->dato);
if(testa->next!=NULL)
printf(" -> ");
else
printf(" -|");
testa=testa->next;
}
}
else
printf("Errore allocazione memoria"),
free(temp);
return 0;
}

I tried out your code and got the repeated printing of the one node which was pointing to itself. What appeared to be missing was when more data was being entered, new nodes needed to be created with memory allocated for each node. With that in mind, following is a refactored version of your code.
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo{
int dato;
struct nodo *next;
}nodo_t;
typedef nodo_t *Ptr_nodo;
int main(){
Ptr_nodo testa,temp;
int q;
temp=NULL;
testa=NULL;
temp=malloc(sizeof(nodo_t));
testa = temp;
if(temp){
q=0;
while(q!=-1){
printf("Insert Value: ");
scanf("%d",&q);
if(q!=-1){
temp->dato=q;
temp->next=malloc(sizeof(nodo_t)); /* Created new node and allocate memory */
temp=temp->next;
temp->next = NULL; /* Make sure this latest node has the NULL terminator */
}
}
while(testa!=NULL){
printf("%d",testa->dato);
if(testa->next!=NULL)
printf(" -> ");
else
printf(" -|");
testa=testa->next;
}
printf("\n"); /* Just added this for appearances on the terminal output */
}
else
printf("Memory allocation error"),
free(temp);
return 0;
}
Some bits to point out.
When another value is received from the user, a new node needs to be created with memory allocated via the "malloc" function.
Pointer references for the previous node and new node need to be updated once the new node is created.
In the new node, its "next" pointer needs to be set to NULL so as to ensure that the subsequent list printing does not get caught up in an endless loop.
With those bits added, following was a sample output at the terminal.
#Vera:~/C_Programs/Console/MultiNode/bin/Release$ ./MultiNode
Insert Value: 4
Insert Value: 1998
Insert Value: 22
Insert Value: 45
Insert Value: 88
Insert Value: -1
4 -> 1998 -> 22 -> 45 -> 88 -> 0 -|
One small side effect I saw was that the final node has a value of zero. I don't know if that is a desired outcome, but I will leave that as something to possibly be refined.
Give that a try and see if it meets the spirit of your project.

draw it out:
temp = malloc(...); // creates a node
+------------+
temp --> | data: ?? |
| next | --> ?? points nowhere right now
+------------+
testa --> NULL
You scanf your data, just call it 5
scanf("%d",&q); // user inputs 5
if(q!=-1){
// set data
temp->dato=q;
temp->next=testa;
+------------+
temp --> | data: 5 |
| next | --> testa, which is NULL right now
+------------+
testa=temp; // results in testa and temp pointing to the same node
+------------+
temp --> | data: 5 |
testa --> | next | --> NULL
+------------+
}
Now you loop back around
scanf("%d",&q); // user inputs 8
if(q!=-1){
// whoops, didn't create a new node, so it's still the same temp from before
temp->dato=q;
temp->next=testa;
testa=temp;
+------------+
temp --> | data: 8 |
testa --> | next | --> testa, which is the same as temp -----+
+------------+ |
^ |
| |
+-------------------------------------------------+
You have one node that points to itself. You need to create a new node on each user entry, I trust the other answer(s) show you how to do that.

You allocated only one node within the program
temp=malloc(sizeof(nodo_t));
if(temp){
//...
Then within the following while loop
while(q!=-1){
printf("Inserire valore: ");
scanf("%d",&q);
if(q!=-1){
temp->dato=q;
temp->next=testa;
testa=temp;
}
}
You are changing the data member dato of the same node because the pointer temp always points to the early allocated single node before the while loop and neither new nodes are being allocated
Its data member next points to the node itself except the first iteration of the loop when the data member next is set to the value of the pointer testa that initially was set to NULL.
So you are outputting the same node that stores the last entered value in its data member dato.
Also if the user at once will enter the value -1 then you will have uninitialized node that results in undefined behavior in the loop where the list is outputted.
You need to allocate new nodes using malloc that will store subsequent entered values. And at the end of the program you should free all the allocated nodes.
Your program can look for example the following way.
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo{
int dato;
struct nodo *next;
}nodo_t;
typedef nodo_t * Ptr_nodo;
int main( void )
{
Ptr_nodo testa = NULL
while ( 1 )
{
Ptr_nodo temp = NULL;
int valore;
printf( "Inserire valore in lista (-1 - esci): " );
if ( scanf( "%d", &valore ) != 1 || valore == -1 || ( temp = malloc( sizeof( *temp ) ) ) == NULL )
{
break;
}
temp->dato = valore;
temp->next = testa;
testa = temp;
}
for ( Ptr_nodo temp = testa; temp != NULL; temp = temp->next )
{
printf( "%d -> ", temp->dato );
}
puts ( "null" );
while ( testa )
{
Ptr_nodo temp = testa;
testa = testa->next;
free( temp );
}
}

Related

Why does my linked list not get printed? ( C language)

I have written a code to enter the name, age, department id, company name, and salary respectively, of employees from a text file into a linked list. Right now, In my code, I have created an insert function and a display function. When I ran the code on the command prompt there were no errors found. However, my list did not get printed. Can someone help me out with this if possible? thankyou.
Here are the details of the file, it is called employee.txt:
Peter 30 1001 Apple 8000
Joseph 50 1002 Oracle 4000
Mary 40 1003 Samsung 6000
Lilly 40 1203 Samsung 7000
Tony 50 1002 Oracle 3000
Jake 30 1005 Apple 3000
Sam 40 1007 Samsung 4000
Lisa 30 1300 Oracle 5000
Kate 50 1200 Apple 6000
Rick 50 1313 Apple 4000
My Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct personTag {
char name[20];
int age;
};
struct officialTag {
int deptId;
char cmpName[20];
double salary;
};
struct employeeTag {
struct personTag personalInfo;
struct officialTag officialInfo;
struct employeeTag *next;
};
typedef struct employeeTag EmpTag;
typedef EmpTag *EmpTagPtr;
void insert(EmpTagPtr *s, char E_name[], int E_age, int E_deptid,
char E_cmpname[], double E_salary);
void displayEmployees(EmpTagPtr s);
int main() {
EmpTagPtr start = NULL;
char E_name[20];
int E_age;
int E_deptid;
char E_cmpname[20];
double E_salary;
// reading employee.txt file
FILE *fp;
fp = fopen("employee.txt", "r");
fscanf(fp, "%s,%d,%d,%s,%lf", E_name, &E_age, &E_deptid, E_cmpname,
&E_salary);
while (!feof(fp)) {
insert(&start, E_name, E_age, E_deptid, E_cmpname,
E_salary); // inserting data to the new node
fscanf(fp, "%s,%d,%d,%s,%lf", E_name, &E_age, &E_deptid, E_cmpname,
&E_salary);
}
fclose(fp);
displayEmployees(start);
return 0;
}
void insert(EmpTagPtr *s, char E_name[], int E_age, int E_deptid,
char E_cmpname[], double E_salary) {
EmpTagPtr current = *s;
EmpTagPtr prev = NULL;
// create an empty node
EmpTagPtr newNode;
newNode = (EmpTag *)malloc(sizeof(EmpTag));
// filling in the values
strcpy(newNode->personalInfo.name, E_name);
newNode->personalInfo.age = E_age;
newNode->officialInfo.deptId = E_deptid;
strcpy(newNode->officialInfo.cmpName, E_cmpname);
newNode->officialInfo.salary = E_salary;
newNode->next = NULL;
while (current != NULL &&
strcmp(current->personalInfo.name, prev->personalInfo.name) > 0) {
prev = current;
current = current->next;
}
if (prev == NULL) {
// add as the first node
newNode->next = *s;
*s = newNode;
} else {
prev->next = newNode;
newNode->next = current;
}
}
void displayEmployees(EmpTagPtr s) {
EmpTagPtr current = s;
while (current != NULL) {
// printing the data part
printf("Employee name: %s\n", current->personalInfo.name);
printf("Company name: %s\n", current->officialInfo.cmpName);
printf("Employee Age: %d\n", current->personalInfo.age);
printf("Department ID: %d\n", current->officialInfo.deptId);
printf("Employee Salary: %lf\n", current->officialInfo.salary);
printf("---------------------------------------------------------");
current = current->next; // move foward the current pointer
}
printf("NULL\n");
}
Your loop to read uses the wrong fscanf format. The loop is also a bit overcomplicated. Just fscanf and check that you successfully extracted the 5 elements. Note the limits for the strings and removed commas:
while (fscanf(fp, "%19s %d %d %19s %lf", E_name, &E_age, &E_deptid,
E_cmpname, &E_salary) == 5)
{
insert(&start, E_name, E_age, E_deptid, E_cmpname, E_salary);
}
The insert function has a buggy loop to find the insertion point. prev will be a NULL pointer here:
while(current != NULL && strcmp(current->personalInfo.name,
prev->personalInfo.name) >0 )
{
prev = current;
current = current->next;
}
Suggested fix:
void insert(EmpTagPtr *s, char E_name[], int E_age, int E_deptid,
char E_cmpname[], double E_salary)
{
// create an empty node
EmpTagPtr newNode = malloc(sizeof *newNode);
// filling in the values
strcpy(newNode->personalInfo.name, E_name);
newNode->personalInfo.age = E_age;
newNode->officialInfo.deptId = E_deptid;
strcpy(newNode->officialInfo.cmpName, E_cmpname);
newNode->officialInfo.salary = E_salary;
// use `newNode` in the comparison:
while (*s && strcmp(newNode->personalInfo.name,
(*s)->personalInfo.name) > 0)
{
s = &(*s)->next;
}
// `s` now points at the `EmpTagPtr` pointer where the new node should
// be inserted for the list to be sorted in alphabetical order.
// If it's the first node to be inserted, `s` points at `start` so
// you do not need `prev` or `current`:
newNode->next = *s;
*s = newNode;
}
Demo
As can be seen in the demo, your program leaks memory so you need to add a function to clean that up.
More about the insertion logic:
Think of start as the next member of an imaginary first dummy node and s starts out pointing at start.
If the linked list has zero elements, start will point at NULL.
*s will therefore be == NULL and the while loop will not do any laps.
You now assign newNode->next = *s (which is NULL) and assign *s = newNode (which means start will point at newNode). The first node is now completely linked.
If the linked list has more than zero elements, the while loop will compare the name of the newNode with that of the dereferenced s's name. EmpTagPtr current = *s; followed by current->personalInfo.name is the same as (*s)->personalInfo.name.
If strcmp(newNode->personalInfo.name, (*s)->personalInfo.name) > 0 we haven't found the insertion point and step s to point at the next node's next member, s = &(*s)->next - and loop to check the conditions again.
If the condition is false it means that newNode should be inserted between the node to which the next member s points at belongs and the *s node - and the loop terminates. When the loop terminates s will therefore point at a next member where the new node should be inserted.
It can be hard to "see" it without actually doing this with pen and paper so I recommend doing just that. Insert 3 nodes using only pen and paper and draw the pointers to see where everything ends up. It usually gives me an "aha!" moment.
As Allan Wind already commented on your question, the first problem was that you had commas in fscanf even though your data is seperated by spaces.
A bigger problem is that segmentation fault occurs in the following while loop in your insert() function
while(current != NULL && strcmp(current->personalInfo.name , prev->personalInfo.name) >0 )
{
prev = current;
current = current->next;
}
This happens because you are accesing personalInfo of prev when prev is set to NULL. I assume that what you wanted to do here is insert an elemente into the linked list so that the list stays sorted alphabetically by names. In that case, you must compare names of current and newNode in strcmp and NOT names of current and prev. Your condition in the while loop should look like this:
while(current != NULL && prev != NULL && strcmp(current->personalInfo.name , newNode->personalInfo.name) > 0 )
I think an important point to improve your programme is database normalization. You might end up with roughly:
Where, person.txt is (an example),
1 Peter 30
2 Joseph 50
3 Mary 40
works.txt
1 1001 8000
2 1002 4000
3 1002 6000
department.txt
1001 1
1002 1
company.txt
1 Apple
Instead of duplicating data, this reduces data redundancy. This is good for if you want to add or make changes to your database. It also mirrors the usage (somewhat) in your programme.

I created a push and pop function in C but do not know how to print them in order

I've recently studied about linked-list and tried to create a push and pop function.
I've successfully created one which look like this.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *next;
};
struct node* buffer = NULL;
void push(int elem){
struct node *new_element = (struct node*)malloc(sizeof(struct node));
new_element->next = buffer;
new_element->data = elem;
buffer = new_element;
}
int pop(void){
int elem = buffer->data;
struct node *eliminate = buffer;
buffer = eliminate->next;
free(eliminate);
return elem;
}
Afterwards I tried to print them this way:
int main(void) {
push(5);
push(7);
push(8);
pop();
printf("%d %d", buffer->data, buffer->next->data);
}
However, the result was 7 5 instead of 5 7. Is there anything wrong with my push function?
After you do:
push(5);
push(7);
push(8);
You have the following linked list:
5 <- 7 <- 8 <- buffer
After the pop you have: 5 <- 7 <- buffer
That is why buffer->data is 7 and buffer->next->data is 5.
In order to print the list in the correct order you will need an pointer pointing to the first node. In your case the 5. Also with your approach you should make it a double linked list.
struct node{
int data;
struct node *next;
};
struct node* start = NULL;
struct node* buffer = NULL;
void push(int elem){
struct node *new_element = (struct node*)malloc(sizeof(struct node));
new_element->next = buffer;
new_element->data = elem;
if (buffer == NULL) start = new_element; // this is the magic
buffer = new_element;
}
Actually, the code is running correctly, this is what your code is doing:
buff=NULL
after push(5): buff=5->NULL
after push(7): buff=7->5->NULL
after push(8): buff=8->7->5->NULL
after pop(): buff=7->5->NULL
thus buffer->data is 7
and buffer->next->data is 5
You should expect 7, 5 as the output. You implemented a Last In First Out stack. This means that the node with data = 8 is the last node pushed onto the stack and the first one out. When you pop that node you are left with 7 and 5 and 7 is on top of the stack.
Here's a link to a good tutorial about stacks
What you experience is the correct behavior. In fact your push() / pop() couple implements a LIFO behavior: Last In, First Out (push() and pop() are actually the common interface name of the functions interacting with the stack abstract data type). The order you expect, instead, would have been shown in case of a FIFO implementation (First In, First Out).
Here is the content of your stack step by step:
push(5);: only an element is present
-----
| 5 |
-----
^
|
buffer
push(7);:
---------
| 7 | 5 |
---------
^
|
buffer
push(8);:
-------------
| 8 | 7 | 5 |
-------------
^
|
buffer
pop();: the last inserted element (8, last in) is removed (first out)
---------
| 7 | 5 |
---------
^
|
buffer
And this is actually what is printed.
Due to the LIFO nature of push 5 - push 7 -push 8 - pop, when 8 is popped (removed from list) only 5 & 7 remain, and these two will appear in reverse of the order in which they were entered.
Furthermore, If you prefer a sorted list of nodes, read on.
"However, the result was "7 5" instead of "5 7". Is there anything wrong with my push function? "
Because the steps do not necessarily have content enter in desired order, you should consider using a sort function in conjunction with printing. Step to a merge sort follow:
MergeSort(headRef)
If the head is NULL or there is only one element in the Linked List
then return.
Else divide the linked list into two halves.
FrontBackSplit(head, &a, &b); /* a and b are two halves */
Sort the two halves a and b.
MergeSort(a);
MergeSort(b);
Merge the sorted a and b (using SortedMerge() discussed here) and update the head pointer using headRef.
*headRef = SortedMerge(a, b);
Excerpt code showing sample implementation from here (see link for full example)
/* Driver program to test above functions*/
int main()
{
/* Start with the empty list */
struct Node* res = NULL;
struct Node* a = NULL;
/* Let us create a unsorted linked lists to test the functions
Created lists shall be a: 2->3->20->5->10->15 */
push(&a, 15);
push(&a, 10);
push(&a, 5);
push(&a, 20);
push(&a, 3);
push(&a, 2);
/* Sort the above created Linked List */
MergeSort(&a);
printf("Sorted Linked List is: \n");
printList(a);
getchar();
return 0;
}
... several other supporting functions
// C code for linked list merged sort
#include <stdio.h>
#include <stdlib.h>
/* Link list node */
struct Node {
int data;
struct Node* next;
};
/* function prototypes */
struct Node* SortedMerge(struct Node* a, struct Node* b);
void FrontBackSplit(struct Node* source,
struct Node** frontRef, struct Node** backRef);
/* sorts the linked list by changing next pointers (not data) */
void MergeSort(struct Node** headRef)
{
struct Node* head = *headRef;
struct Node* a;
struct Node* b;
/* Base case -- length 0 or 1 */
if ((head == NULL) || (head->next == NULL)) {
return;
}
/* Split head into 'a' and 'b' sublists */
FrontBackSplit(head, &a, &b);
/* Recursively sort the sublists */
MergeSort(&a);
MergeSort(&b);
/* answer = merge the two sorted lists together */
*headRef = SortedMerge(a, b);
}

Taking values from stdin and storing those in linked list nodes

Yesterday after I did a stupid approach, I think I am on a good way right now. The thing I wanna program is that I am getting n values from the user and I am trying to store every value into a linked list node which has to be sorted after every input.
So it means:
Input:
5 1 9
Output:
1 5 9
Input:
2 3
Output:
1 2 3 5 9
My code so far:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node {
int val;
struct node* next;
} node;
void printList(node* n) {
while (n != NULL) {
printf("%d ", n->val);
n = n->next;
}
}
void push(node * head, int val) {
node * current = head;
while (current->next != NULL) {
current = current->next;
}
/* now we can add a new variable */
current->next = malloc(sizeof(node));
current->next->val = val;
current->next->next = NULL;
}
int main() {
char input[20];
char* ptr;
node* head = NULL;
head = (node*) malloc(sizeof(node));
do {
printf("Eingabe:");
fgets(input,20,stdin);
ptr = strtok(input," ");
while(ptr!=NULL){
int val = atoi(ptr);
push(head,val);
ptr = strtok(NULL, " ");
}
printList(head);
}
while(*input != '0');
return 0;
}
Edited my code, node creation is working , but when I input 5 1 9 , it outputs 0 5 1 9 where is that 0 coming from?
The 0 is the value of your head.
When you create the first node you add it as the next of the head, this means that by having as input 5 1 9 your linked list will be:
head -> 5 -> 1 -> 9
When you print you don't just print the values of the nodes you have created but also the value of the head, since the value was never initialized and in the struct it's an int your compiler intializes it to 0 automatically (this depends on the compiler implementation so it's always better to initialize it).
If you don't want that 0 in the front you have a couple of options:
assign to head->value the first number that you input
call the printList as printList(head->node)
change your linked list implementation to not have the head hold a value
change printList to:
void printList(node* n) {
n = n->next;
while (n != NULL) {
printf("%d ", n->val);
n = n->next;
}
}
The correct approach could be (pseudo-code):
[START]
Read new line from the STDIN;
While there are new values:
Read new value;
Add it on new node (easier adding on top of the list);
Sort the list;
Print the list;
Loop to [START]
In your code you are missing the "sort the list" phase.
Easier if you add a swap function and try one of sorting algorithm on your choice

Using fgets to read lines from a file into Binary Search Tree

Currently i'm trying to store each separate line in my file into a string, and then store it in a binary search tree, but a problem occurs. For some reason when I print my BST only the last line is outputted and not the first 3. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int count;
char* key;
struct node* left;
struct node* right;
};
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = item;
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
void printInorder(struct node* root)
{
if(root != NULL)
{
printInorder(root->left);
printf("%s \n", root->key);
printInorder(root->right);
}
}
struct node* insert(struct node* node, char* key)
{
if(node == NULL)//When tree is empty
return newNode(key);
if(strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
if(strcmp(key, node->key) > 0)
node->right = insert(node->right, key);
return node;
};
int main()
{
struct node *root = NULL;
int i = 0;
char str[100];
FILE* fp;
fp = fopen("textFile.txt", "r");
if ((fp = fopen("textFile.txt","r")) == NULL)
{
printf("Could not open textFile.txt\n");
exit(1);
}
while(fgets(str, 100, fp) != NULL)
{
++i;
root = insert(root, str);
printf("%3d: %s", i, str);
}
printf("bst printed\n");
printInorder(root);
return 0;
}
textFile.txt contains
bob is working.
david is a new hire.
alice is bob's boss.
charles doesn't like bob.
And when the bst is printed the only line that is outputted is the last one
Charles doesn't like bob.
Any help would really be appreciated.
Notice that when you create a node with newNode, you store a copy of the pointer passed into it, rather than a copy of the string being pointed at. This means that every time you insert a value into the tree, it stores a pointer to the str buffer in main. In other words, after you do your first insertion, things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | b | o | b | | i | | 0 |
+------------+ +---+---+---+---+---+...+---+
When you then read the next line of the file, you're overwriting str with the contents of that line, so the picture looks like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | d | a | v | i | d | | 0 |
+------------+ +---+---+---+---+---+...+---+
Notice that your BST now acts as though it contains "david is a new hire" even though you never inserted that value. As a result, when you try inserting "david is a new hire" into the BST, nothing happens.
The same thing happens for the next few reads, until eventually you read the final line of the file, when things look like this:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | c | h | a | r | l | | 0 |
+------------+ +---+---+---+---+---+...+---+
This is why you're only seeing the line about Charlie at the end - the BST is directing you to the single shared copy of the buffer.
To fix this, make your BST store copies of the strings passed into it, or copy the strings before storing them in the tree. For example, you might have the newNode function call strdup to get its own copy of the string to store:
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = strdup(item); // <--- here!
/* TODO: Error-handling! */
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
That should fix your issue. Just make sure to deallocate everything when you're done!

Linked list doesn't work

I have the following code, when I add nodes why does it reset all nodes to the most recent nodes data? Assuming everything else in the codes works correctly, parsing etc. can anyone identify a problem with the list. See output at the bottom.
typedef char* string;
typedef struct linked_list listType;
typedef struct linked_list* linked_list;
typedef struct node NodeType;
typedef struct node* Node;
typedef enum boolean{
true = 1,
false = 0
}boolean;
struct node{
Node next;//next node in the list
string *transData;//listAdd--->string data[]
};
struct linked_list{
Node head;//first node in the list
int size;//size of list, number of nodes in list
};
boolean add(linked_list list, string *data)
{
boolean retval = false;//default retval is false
Node nod;//node to add
nod = (Node)malloc(sizeof(NodeType));
nod->transData = data;
nod->next = NULL;
//list size is 0
if(list->head == NULL)
{
list->head = nod;
printf("First Node added: '%s'\n", nod->transData[0]);fflush(stdout);
retval = true;
}
//nodes already in list
else
{
printf("List with nodes already\n");
fflush(stdout);
Node node = list->head;
//iterating through nodes
while(node->next != NULL)
{
node = node->next;
}//while
node->next = nod;
printf("Node added: '%s'\n", nod->transData[0]); fflush(stdout);
retval = true;
}
list->size+=1;
return retval;//success
}
/**
* Returns the size of the list.
*/
int listSize(linked_list list)
{
return list->size;
}
/**
*Can only print with 2 or more elements
*/
void printList(linked_list list)
{
int i=0;
Node nod = list->head;
int length = listSize(list);
printf("ListSize:%d\n",listSize(list));
fflush(stdout);
while(nod->next != NULL)
{
printf("Node %d's data: %s\n", i, nod->transData[0]);
fflush(stdout);
nod = nod->next;
i++;
}
}//printlist
Output:
trans 5 5
Argument 1: trans
Argument 2: 5
Argument 3: 5
Last spot(4) is: (null)
name of command: trans
ID 1
First Node added: 'trans'
ListSize:1
>>check 4
Argument 1: check
Argument 2: 4
Last spot(3) is: (null)
name of command: check
ID 2
List with nodes already
Node added: 'check'
ListSize:2
Node 0's data: check
>>trans 4 4
Argument 1: trans
Argument 2: 4
Argument 3: 4
Last spot(4) is: (null)
name of command: trans
ID 3
List with nodes already
Node added: 'trans'
ListSize:3
Node 0's data: trans
Node 1's data: trans
>>check 5
Argument 1: check
Argument 2: 5
Last spot(3) is: (null)
name of command: check
ID 4
List with nodes already
Node added: 'check'
ListSize:4
Node 0's data: check
Node 1's data: check
Node 2's data: check
(The OP tells me that the nodes need to have arrays of strings, so the pointer-to-a-pointer thing is actually correct).
Anyhow, it looks like your problem is that every node has a pointer to the same buffer. You just keep copying different strings into the same buffer, and then you assign the address of a pointer to that buffer to each new node.
First, I'd get rid of those typedefs. I don't know how much clarity they're really adding.
Next, you need to allocate new storage for each string. The standard library strdup() function is a handy way to do that:
// Turns out it's a fixed-size array, so we can blow off some memory
// management complexity.
#define CMDARRAYSIZE 21
struct node {
Node next;
char * transData[ CMDARRAYSIZE ];
};
// Node initialization:
int i = 0;
struct node * nod = (struct node *)malloc( sizeof( struct node ) );
// Initialize alloc'd memory to all zeroes. This sets the next pointer
// to NULL, and all the char *'s as well.
memset( nod, 0, sizeof( struct node ) );
for ( i = 0; i < CMDARRAYSIZE; ++i ) {
if ( NULL != data[ i ] ) {
nod->transData[ i ] = strdup( data[ i ] );
}
}
...but then be sure that when you free each node, you call free( nod->transData[n] ) for every non-NULL string pointer in nod->transData. C is not a labor-saving language.
Your issue is probably due to pointer copying. You are likely referencing the same buffer in all your nodes. Try to make a copy of your string data with strdup for example.
Not the main issue, but your printList won't print out the last element.
Instead of while(nod->next != NULL) use while(nod != NULL)

Resources