Linked Lists (very intro) InsertBack - c

#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
typedef struct node node;
node* insertFront(node* head, int d);
node* insertBack(node* head, int d);
void print(node* head);
int max(node* head);
int min(node* head);
int locInList(node* head, int x);
int main()
{
node* head = NULL;
node* temp = NULL;
head = malloc(sizeof(node));
head = insertBack(head, 5);
head = insertFront(head, 4);
head = insertFront(head, 3);
head = insertBack(head, 6);
head = insertBack(head, 7);
print(head);
printf("\nMax: %d\n", max(head));
printf("Min: %d\n", min(head));
printf("locInList 5: %d\n", locInList(head, 5));
printf("locInList 9: %d\n", locInList(head, 9));
return 0;
}
node* insertFront(node* head, int d)
{
node *tmp = NULL;
tmp = malloc(sizeof(node));
tmp->data = d;
tmp->next = head;
head = tmp;
return head;
}
node* insertBack(node* head, int d)
{
node *ptr;
ptr->data=d;
ptr->next = NULL;
if(head==NULL)
{
head->data=d;
head->next=NULL;
}
else
{
node *temp=head;
while(temp->next != NULL)
{
temp=temp->next;
}
temp->next=ptr;
}
return head;
}
void print(node* head)
{
node *tmp = head;
while(tmp != NULL)
{
printf("%d ", tmp->data);
tmp = tmp->next;
}
}
int max (node* head)
{
int max;
while (head != NULL)
{
if (max > head->data)
max = head->data;
}
return max;
}
int min (node* head)
{
int min;
while (head != NULL)
{
if (min < head->data)
min = head->data;
}
return min;
}
int locInList(node* head, int x)
{
}
I'm having trouble with my InsertBack function, I want to add the value of d to the end of head.
The current output I'm getting with this code is:
3 4 0 7 7 7 7 7 7 7...repeating
The output should look like this
34567
Max: 7
Min: 3
Any help would be appreciated. I'm also very new to linked lists. So any help would be very appreciated!!

Here
node* insertBack(node* head, int d)
{
node *ptr;
ptr->data=d; // Dereference uninitialized pointer !!
ptr->next = NULL; // Dereference uninitialized pointer !!
if(head==NULL)
{
head->data=d; // Dereference NULL pointer !!
head->next=NULL; // Dereference NULL pointer !!
}
you have a major problem. You don't allocate memory! So you are dereferencing an uninitialized pointer. That's bad.
Try:
node* insertBack(node* head, int d)
{
node *ptr = malloc(sizeof *ptr);
ptr->data=d;
ptr->next = NULL;
if(head==NULL) return ptr;
...

For starters this statement in the beginning of main
head = malloc(sizeof(node));
does not make sense. You created an uninitialized node. As a result the program already invokes undefined behavior if you will try to perform any operation with the list except freeing the allocated memory.
Remove this statement.
You forgot to allocate memory for a node in the function insertBack.
node* insertBack(node* head, int d)
{
node *ptr;
ptr->data=d;
ptr->next = NULL;
//...
Also the body of the if statement
if(head==NULL)
{
head->data=d;
head->next=NULL;
}
does not make sense.
If to leave the function declaration as is then its definition can look the following way
node * insertBack( node *head, int d )
{
node *ptr = malloc( sizeof( node ) );
ptr->data = d;
ptr->next = NULL;
if ( head == NULL )
{
head = ptr;
}
else
{
node *temp = head;
while ( temp->next != NULL )
{
temp = temp->next;
}
temp->next = ptr;
}
return head;
}
Also these functions
int max (node* head)
{
int max;
while (head != NULL)
{
if (max > head->data)
max = head->data;
}
return max;
}
int min (node* head)
{
int min;
while (head != NULL)
{
if (min < head->data)
min = head->data;
}
return min;
}
are invalid because at least variables max and min were not initialized. Moreover they have an infinite loop and for example the function max is not finding the maximum value in the list.:)
It would be better to declare them like for example this
int max ( node* head, int *value );
In this case the definition of the function max could look like
int max( node* head, int *value )
{
int success = head != NULL );
if ( success )
{
*value = head->data;
while ( ( head = head->next ) != NULL )
{
if ( *value < head->data ) *value = head->data;
}
}
return success;
}
and the function can be called like
int max_value;
if ( max( head, &max_value ) )
{
printf( "The maximum value is %d\n", max_value );
}
The function min could be declared and defined the same way.
If to leave the function declarations as is then you have at least initialize the variables to 0. For example
int max (node* head)
{
int max = head == NULL ? 0 : head->data;
for ( ; head != NULL; head = head->next )
{
if ( max < head->data ) max = head->data;
}
return max;
}
The similar way can be defined the function min. Though as I pointed out it is better when the functions are defined the way I showed above.
And do not forget to write a function that will free the all allocated memory.

Related

Convert array to singly linked list

I have more experience with linked lists after gaining practice and support from SO, given my last few questions. Essentially, I am now following an algorithm that will convert an array to a singly linked list.
Algorithm: CONVERT (A, N, HEAD)
1. Set HEAD = NULL
2. Repeat steps 3 to 8 while N ≠ -1
3. Allocated memory for NEW node
4. IF NEW = NULL then Print: “Memory not Available” and Return
5. Set NEW→DATA = A[N-1]
6. Set NEW→LINK = HEAD
7. Set HEAD = NEW
8. Set N = N - 1
[End of loop]
9. Return
I have attempted creating the code for this, however, after printing out the node carrying the data, I get a bunch of zeros. I know that with an array, if I assign a large size to the array and do not fill all values in, then these are assigned 0. However, this is not the case for my example.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int DATA;
struct node* LINK;
} node;
void convert(int A[], int N, node* head){
head = NULL;
while(N != -1){
node* new;
new = (node*)malloc(sizeof(node));
if (new == NULL){
printf("Memory not available");
return;
}
printf("%i", new->DATA);
new->DATA = A[N-1];
new->LINK = head;
head = new;
N--;
}
return;
}
int main(){
int arr[10] = {0, 1, 2, 3, 4};
int size = sizeof(arr)/sizeof(arr[0]);
node* former;
former = (node*)malloc(sizeof(node));
convert(arr, size, former);
return 0;
}
Would print out the following:
00000000000%
How do I convert the array values to the singly linked list, what might I be missing?
There are a few problems with your code:
You don't receive the created list head pointer back to main.
You print the data before you assign it and the printing will be inverted if you do during the creation of the list.
You don't free the allocated memory and create memory leaks.
Here is how to fix it:
Return the created list head pointer from the convert function.
Write a separate function for printing the list.
Write a function for freeing the memory of the list.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int DATA;
struct node *LINK;
} node;
node *convert(int A[], int N);
void printList(node *head);
void freeList(node *head);
node *convert(int A[], int N)
{
node *head = NULL;
for (int i = N - 1; i >= 0; i--)
{
node *new = malloc(sizeof(node));
if (new == NULL)
{
printf("Memory not available");
freeList(head); // free already allocated memory
return NULL;
}
new->DATA = A[i];
new->LINK = head;
head = new;
}
return head; // return the head pointer
}
void printList(node *head)
{
node *current = head;
while (current != NULL)
{
printf("%d ", current->DATA);
current = current->LINK;
}
}
void freeList(node *head)
{
node *current = head;
node *next = NULL;
while (current != NULL)
{
next = current->LINK;
free(current);
current = next;
}
}
int main()
{
int arr[5] = {0, 1, 2, 3, 4};
int size = sizeof(arr) / sizeof(arr[0]);
node *former = convert(arr, size);
printList(former);
freeList(former);
return 0;
}
Seems you are trying to print new->DATA value before you assign it's value. print it after assigning the value.
And head pointer is a local variable, so it's changes will not be reflected in Main() function. Change head pointer as follows inside Convert() function.
*head = NULL;
And your Main() function should be updated as follows,
int main(){
int arr[10] = {0, 1, 2, 3, 4};
int size = sizeof(arr)/sizeof(arr[0]);
node* head;
convert(arr, size, &head);
return 0;
}
updated:
Change your Convert() function as follows,
void convert(int A[], int N, node ** head) {
* head = NULL;
while (N != -1) {
node * new;
new = malloc(sizeof new[0]);
if (new == NULL) {
printf("Memory not available");
return;
}
new -> DATA = A[N - 1];
printf("%i", new -> DATA);
new -> LINK = * head;
* head = new;
N--;
}
return;
}
Split the problem into smaller bits. Use functions to program them.
typedef struct node {
int DATA;
struct node* LINK;
} node;
node *add(node *last, int data)
{
node *wrk = malloc(sizeof(*wrk));
if(wrk)
{
wrk -> DATA = data;
wrk -> LINK = NULL;
}
if(last) last -> LINK = wrk;
else last = wrk;
return wrk;
}
node *convert(int *data, size_t size)
{
node *head = NULL, *last;
if(data && size)
{
if((head = add(NULL, *data++)))
{
last = head;
while(--size)
{
if(!(last = add(last, *data++))) break;
}
}
}
return head;
}
void printList(const node *head)
{
while(head)
{
printf("%d\n", head -> DATA);
head = head -> LINK;
}
}
int main(void)
{
int arr[] = {9, 1, 2, 3, 4};
size_t size = sizeof(arr)/sizeof(arr[0]);
node *head = convert(arr, size);
printList(head);
return 0;
}

Reverse Every K Nodes

Every k nodes form a segment. If the last few nodes are less than K, then you can ignore them.
Write a reverseKnodes() which reserves every segment in the linked list.
The function prototype is given as follow: void reversekNodes(ListNode** head, int k);
Input format:
The 1st line is the k
The 2nd line is the data to create the linked list and ends with a non-digit symbol Example:
Input: 3 1 2 3 4 5 6 7 8 9 10 a
Output: 3 2 1 6 5 4 9 8 7 10
#include <stdio.h>
#include <stdlib.h>
struct _listNode
{
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList (ListNode * head);
void deleteList (ListNode ** ptrHead);
void reverseKNodes (ListNode ** head, int K);
int
main ()
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
scanf ("%d", &K);
while (scanf ("%d", &i))
{
if (head == NULL)
{
head = (ListNode *) malloc (sizeof (ListNode));
temp = head;
}
else
{
temp->next = (ListNode *) malloc (sizeof (ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes (&head, K);
printList (head);
deleteList (&head);
return 0;
}
void
printList (ListNode * head)
{
while (head != NULL)
{
printf ("%d ", head->item);
head = head->next;
}
printf ("\n");
}
void
deleteList (ListNode ** ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL)
{
temp = cur->next;
free (cur);
cur = temp;
}
*ptrHead = NULL;
}
void
reverseKNodes (ListNode ** head, int K)
{
struct _listNode *reverse (struct _listNode *head, int k){
if (!head)
return NULL;
struct _listNode* cur = head;
struct _listNode* next = NULL;
struct _listNode* prev = NULL;
int count = 0;
while (cur != NULL && count < K)
{
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
}
I am not allowed to change anything else other than the void function for reverseKNodes and I know I have done it wrong but I dont know where I went wrong. Could someone help me please?
A few issues with nested functions ...
Nested functions aren't standard C.
Are of limited benefit.
They add extra overhead to invoke.
So [please] don't use them.
And, your usage of one is incorrect. In reverseKNodes, you define reverse but never call it. So, reverseKNodes is a no-op.
So, to fix, move reverse out of the body of reverseKNodes and place it above. Then, actually invoke it in reverseKNodes:
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the full refactored code. For aid in debug (e.g. with gdb), I added code to allow the program to take an input file as an argument.
#include <stdio.h>
#include <stdlib.h>
struct _listNode {
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList(ListNode *head);
void deleteList(ListNode **ptrHead);
void reverseKNodes(ListNode **head, int K);
int
main(int argc,char **argv)
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
--argc;
++argv;
FILE *xf;
do {
if (argc != 1) {
xf = stdin;
break;
}
xf = fopen(*argv,"r");
if (xf != NULL)
break;
perror(*argv);
exit(1);
} while (0);
fscanf(xf,"%d", &K);
while (fscanf(xf,"%d", &i)) {
if (head == NULL) {
head = (ListNode *) malloc(sizeof(ListNode));
temp = head;
}
else {
temp->next = (ListNode *) malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes(&head, K);
printList(head);
deleteList(&head);
return 0;
}
void
printList(ListNode *head)
{
while (head != NULL) {
printf("%d ", head->item);
head = head->next;
}
printf("\n");
}
void
deleteList(ListNode **ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL) {
temp = cur->next;
free(cur);
cur = temp;
}
*ptrHead = NULL;
}
struct _listNode *
reverse(struct _listNode *head, int K)
{
if (! head)
return NULL;
struct _listNode *cur = head;
struct _listNode *next = NULL;
struct _listNode *prev = NULL;
int count = 0;
while (cur != NULL && count < K) {
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the program output:
3 2 1 6 5 4 9 8 7 10

Printing a doubly linked list in reverse only printing first element

Writing a function to print a doubly linked list in reverse. The function stops after only printing 7 and does not print the rest of the items in the list. My programs and functions are below.
Edited to include code that didn't paste. Having issues copying and pasting with Putty my apologies.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
struct node *prev;
};
typedef struct node node;
void printRev(node* head);
node* removeNode(node* head, int d);
node* insertFront(node* head, int d);
node* insertBack(node* head, int d);
void print(node* head);
int max(node* head);
int min(node* head);
int locInList(node* head, int x);
int main()
{
node* head = NULL;
head = insertFront(head, 5);
head = insertFront(head, 4);
head = insertBack(head, 6);
head = insertBack(head, 7);
print(head);
printRev(head);
printf("Max: %d\n", max(head));
printf("Min: %d\n", min(head));
printf("locInList 5: %d\n", locInList(head, 5));
printf("locInList 9: %d\n", locInList(head, 9));
head = removeNode(head, 6);
print(head);
head = removeNode(head, 4);
print(head);
head = removeNode(head, 7);
print(head);
return 0;
}
void printRev(node* head) {
node *cur = head;
node *tmp = NULL;
if (cur == NULL) {
return;
}
else {
while(cur->next != NULL) {
cur = cur->next;
}
while(cur != NULL) {
printf("%d ", cur->data);
cur = cur->prev;
}
}
printf("\n");
}
node* removeNode(node* head, int d)
{
node *tmp = head->next;
head->data = head->next->data;
head->next = tmp->next;
free(tmp);
return head;
}
node* insertFront(node* head, int d)
{
node *tmp = NULL;
tmp = malloc(sizeof(node));
tmp->data = d;
tmp->next = head;
head = tmp;
return head;
}
node* insertBack(node* head, int d)
{
node *tmp = malloc(sizeof(node));
tmp->data = d;
tmp->next = NULL;
if(head == NULL){
return head;
}
}
else{
node *end = head;
while(end->next != NULL){
end = end->next;
}
end->next = tmp;
}
return head;
}
void print(node* head)
{
node *tmp = head;
while(tmp != NULL){
printf("%d ", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
int max (node* head)
{
int max = head->data;
node *tmp = NULL;
tmp = head;
while(tmp->next != NULL){
if(tmp->data >= max){
max = tmp->data;
}
tmp = tmp->next;
}
}
return min;
}
int locInList(node* head, int x)
{
int i = 0;
node *tmp = NULL;
tmp = head;
while(tmp != NULL){
if(tmp->data == x){
return i;
}else{
i++;
tmp = tmp->next;
} }
return -1;
}
Expected results are - 7 6 5 4
Received results are - 7
Neither insertFront nor insertBack set prev, which is the root cause of your problem. (Your reverse iteration loop critically depends on the prev pointers having been set correctly.)
As it's a doubly linked list, you should point your head's back pointer to temp(new inserted one) in the function insertFront. So it should be ;
node* insertFront(node* head, int
d)
{
node *tmp = NULL;
tmp = malloc(sizeof(node));
tmp->data = d;
tmp->prev=NULL:
if(head==NULL)
return tmp;
head->prev=tmp;
tmp->next = head;
return tmp;
}
Similarly in insertBack function take care of making prev pointer point to previous node in the list.

Segmentation Fault on Linked List Using C

I am new to C and try to learn how to implement C on linked list. I am really confused why I can't access myList in the main function? because when I try to myList->data, it's segmentation fault. I think there's some error in my addtohead function?
Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
Your addToHead function is supposed to return the mallocated memory back to caller.
So you should assign the return value to mylist at first:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
Into your addToHead function you wrote
head = temp;
But head has local scope and the assigned value is not reflected to the pointer myList.
To do so you have to use pointer to pointer.
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
Finally always remember to check the malloc return value: it can fail.
You return the new head node from addToHead, but you don't do anything with it. You need to assign this value to myList to update it:
myList = addToHead(myList, input);
Also, you misspelled a variable on the following line:
printf("%d \n", myListd->data);
It should be:
printf("%d \n", myList->data);
In this function definition
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
The parameter node* head is a local variable of the function. Any changes of the parameter will not influence on the original argument. The function parameters will be destroyed after exiting the function.
You can consider the function definition and its call the following way
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
So the original variable myList will not be changed after the function call. You have to assign explicitly the returned value to the variable
myList = addToHead(myList, input);
Also the function has a drawback. It does not report an error in case when the new node was not allocated.
A better approach to write the function looks the following way
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
In this case the function can be called in a loop the following way
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}

LinkedList adding Element

We have a problem with our LinkedList in C.
When I count how many nodes should be in the list, I always get 1
LL count: 1
This is the Add, count and get last element of the list code:
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
newNode->ID=-1;
newNode->TCB=-1;
newNode->next = DEF_NULL;
if(!head) head = newNode;
else tail->next = newNode;
}
}
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != DEF_NULL)
{
temp = temp->next;
}
return temp;
}
CPU_INT32U countLL(LL * head)
{
CPU_INT32U elements = 0;
LL * temp = head;
while(temp->next != DEF_NULL)
{
temp = temp->next;
elements++;
}
return elements;
}
It's called in this way:
addLL(list);
temp = countLL(list);
Debug_LOG("LL count: %i", temp);
where LL * list; is a global variable, and temp is in local scope.
I hope anyone can see where I went wrong
Greetings,
Sjaak and Gerrit
I see several issues in your code :
you should always protect your linked list operations by testing if the list pointer is valid (i.e. not null)
you cannot allocate a first item to an empty list due to the way you allocate the first new item : you change head but the modification won't be propagated outside of the function. You should pass a "pointer to a list pointer" (i.e. a LL**) that is equivalent to "the address of a LL*"; See how I call addLL() and how I have modified its prototype and the head assignment
if your list is only one block long, it won't be counted as you count only if there is a successor, see how I have modifed the order of the do / while condition
I propose the modified code that works for 1, 2 or any list length (I have just changed the CPU_INT32U to int to compile quickly with MinGW, I could have typedef'ined):
#include <stdio.h>
#define DEF_NULL 0
typedef struct tagL {
int ID;
int TCB;
struct tagL *next;
} LL;
void addLL(LL ** head);
LL * getLastNode(LL * head);
int countLL(LL * head);
void addLL(LL ** head)
{
LL *newNode;
LL *tail = getLastNode(*head);
newNode = malloc(sizeof(LL));
if(newNode != DEF_NULL)
{
newNode->ID=-1;
newNode->TCB=-1;
newNode->next = DEF_NULL;
if(!*head)
*head = newNode;
else
tail->next = newNode;
}
}
LL * getLastNode(LL * head)
{
LL *temp = head;
if (head){
while(temp->next != DEF_NULL)
{
temp = temp->next;
}
}
return temp;
}
int countLL(LL * head)
{
int elements = 0;
LL * temp = head;
if (head){
do {
temp = temp->next;
elements++;
} while(temp != DEF_NULL);
}
return elements;
}
int main(int argc, char *argv[]){
LL *list = 0;
printf("LL test\n");
addLL(&list);
printf("length = %d\n", countLL(list));
addLL(&list);
printf("length = %d\n", countLL(list));
addLL(&list);
printf("length = %d\n", countLL(list));
}
Output :
LL test
length = 1
length = 2
length = 3
On Windows nothing's wrong whit this function - strange ...
ideone also shows good output.
#include <stdio.h>
#include <stdlib.h>
typedef struct LL{
struct LL *next;
}LL;
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != NULL)
{
temp = temp->next;
}
return temp;
}
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
newNode = malloc(sizeof(LL));
if(newNode != NULL)
{
newNode->next = NULL;
if(!head) head = newNode;
else tail->next = newNode;
}
}
int countLL(LL * head)
{
int elements = 0;
LL * temp = head;
while(temp->next != NULL)
{
temp = temp->next;
elements++;
}
return elements;
}
int main() {
LL *h = malloc(sizeof(*h));
addLL(h);
addLL(h);
addLL(h);
printf("%d\n", countLL(h)); // prints 3 as expected
}
CPU_INT32U countLL(LL * head){CPU_INT32U elements = 0;LL * temp = head;while(temp->next != DEF_NULL){temp = temp->next;elements++;}return elements;}
in this function you are declaring elements variable as auto
so its storage gets deallocated as soon as function exits , as memory now free to allocate to different variable, so may be overwritten hence previous cvalue gets lost
so to avoid this please use static in declaring variable.....
as static variables memory gets deallocated only after execution of whole program
please try....
void addLL(LL * head)
{
LL *newNode;
LL *tail = getLastNode(head);
There is a problem here, if (the global) head happens to be NULL, it will be dereferenced by the getLastNode() function:
LL * getLastNode(LL * head)
{
LL *temp = head;
while(temp->next != DEF_NULL)
Here temp->next != ... will cause temp to be dereferenced. That would cause NULL pointer dereferences if temp happens to be NULL. (as in the call by the insert function. You could add an extra test (or use pointers to pointers which is cleaner):
while(temp && temp->next != DEF_NULL)
Update (to show that the pointer to pointer version is cleaner)
#include <stdlib.h>
#include <stdio.h>
#define DEF_NULL NULL
#define CPU_INT32U unsigned
typedef struct link {
struct link *next;
} LL;
LL *globhead=NULL;
LL **getTailPP(LL **ppHead);
CPU_INT32U countLL(LL * ptr);
void addLL(LL **ppHead);
void addLL(LL **ppHead)
{
ppHead = getTailPP(ppHead);
*ppHead = malloc(sizeof **ppHead);
if(*ppHead != DEF_NULL)
{
// newNode->ID=-1;
// newNode->TCB=-1;
(*ppHead)->next = DEF_NULL;
}
}
LL **getTailPP(LL **ppHead)
{
for( ; *ppHead; ppHead = &(*ppHead)->next ) {;}
return ppHead;
}
CPU_INT32U countLL(LL * ptr)
{
CPU_INT32U elements = 0;
for(; ptr != DEF_NULL; ptr=ptr->next) { elements++; }
return elements;
}
int main()
{
unsigned count;
addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);
addLL( &globhead);
count = countLL (globhead);
printf("count = %u\n", count);
return 0;
}

Resources