void add(queue currentQueue, int data){
You are passing a copy of the queue struct to add, so only the copy's members are changed. You need to pass a queue* to the function to be able to change the members of the queue itself.
void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}
and call it as add(&your_queue);
In your addTail function, you should check whether head is NULL too.
And with
node *newNode = (struct listNode *)malloc(sizeof(node));
newNode = initNode(value, length);
in addTail, you have a serious problem. With the assignment newNode = initNode(value, length);, you are losing the reference to the just malloced memory.
If initNode mallocs a new chunk of memory, it's "just" a memory leak, then you should remove the malloc in addTail.
Otherwise, I fear initNode returns the address of a local variable, à la
node * initNode(int val, int len) {
node new;
new.nodeValue = val;
new.nodeLength = len;
new.next = NULL;
return &new;
}
If initNode looks similar to that, that would cause a problem since the address becomes invalid as soon as the function returns. But your compiler should have warned you, if initNode looked like that.
Anyway, without seeing the code for initNode, I can't diagnose the cause.
But if you change your addTail to
void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
it should work.
However, since you have pointers to the first and the last node in the list, it would be more efficient to use the back pointer to append a new node,
void add(queue *currentQueue, int data){
node *newNode = malloc(sizeof *newNode);
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = data;
newNode->nodeLength = data+5;
newNode->next = NULL;
currentQueue->back->next = newNode;
currentQueue->back = newNode;
}
since you needn't traverse the entire list to find the end.
A simple sample programme
#include <stdlib.h>
#include <stdio.h>
struct listNode {
int nodeLength;
int nodeValue;
struct listNode *next;
};
typedef struct listNode node;
struct QueueRecord {
node *list;
node *front;
node *back;
int maxLen;
};
typedef struct QueueRecord queue;
node *createList (){
node *head = NULL;
head = (struct listNode *)malloc(sizeof(node));
head->next = NULL;
return head;
}
void addTail (node *head, int value, int length) {
if (head == NULL) { // violation of contract, die loud
exit(EXIT_FAILURE);
}
node *current = head;
node *newNode = malloc(sizeof(node));
if (newNode == NULL) {
exit(EXIT_FAILURE); // or handle gracefully if possible
}
newNode->nodeValue = value;
newNode->nodeLength = length;
newNode->next = NULL;
while (current->next != NULL)
current = current->next;
current->next = newNode;
}
queue createQueue(int maxLen){
queue newQueue;
newQueue.list = createList();
newQueue.front = newQueue.list;
newQueue.back = newQueue.list;
newQueue.maxLen = maxLen;
return newQueue;
}
void add(queue *currentQueue, int data){
if (currentQueue == NULL) {
exit(EXIT_FAILURE);
}
addTail(currentQueue->list, data, data+5);
currentQueue->back = currentQueue->back->next;
}
int main(void) {
queue myQ = createQueue(10);
for(int i = 1; i < 6; ++i) {
add(&myQ, i);
printf("list: %p\nfront: %p\nback: %p\n",
(void*)myQ.list, (void*)myQ.front, (void*)myQ.back);
}
node *curr = myQ.front->next;
while(curr) {
printf("Node %d %d, Back %d %d\n", curr->nodeValue,
curr->nodeLength, myQ.back->nodeValue, myQ.back->nodeLength);
curr = curr->next;
}
while(myQ.list) {
myQ.front = myQ.front->next;
free(myQ.list);
myQ.list = myQ.front;
}
return 0;
}
works as expected, also with the alternative add implementation.