Doubly Linked-List stops working

Hi all,
I try to implement a doubly linked-list that holds task control blocks (TCBs), each of which contains a pointer to function and a void pointer. I write a sketch to perform blinking led but nothing happens. My sketch is as follows:

#include <scheduler.h>

Queue *q;
TCB *currentTask;

void blinking(void *data) {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  q->QueueInsert(NULL, blinking);
  currentTask = q->head;
}

// the loop function runs over and over again forever
void loop() {  
  currentTask->function(currentTask->data);
}

scheduler.h:

#ifndef SCHEDULER_H_
#define SCHEDULER_H_

#include "stdlib.h"

typedef void (*task)(void *data);

class TCB {
public:
	void *data;		
	TCB *next;
	TCB *prev;
public:
	void (*function)(void *);
};

class Queue {
public:
	TCB *head;
	TCB *tail;
	int count;
	
public:
	void QueueInsert(void *data, task myTask);
	void QueueRemove(TCB *task);
};

#endif

scheduler.cpp:
[/code]
#include “scheduler.h”

// Insert at tail
void Queue::QueueInsert(void *value, task myTask)
{
TCB newTask = (TCB)calloc(1, sizeof(TCB));

newTask->data = value;
newTask->function = myTask;

if(head == NULL) {
head = newTask;
tail = newTask;
} else {
tail->next = newTask;
newTask->prev = tail;
tail = newTask;
}

count++;
}

// Remove a particular node in queue
void Queue::QueueRemove(TCB *task)
{
if(head == NULL) {
// do nothing
}

if(task == head && task == tail) {
head = NULL;
tail = NULL;
} else if(task == head) {
head = task->next;
head->prev = NULL;
} else if(task == tail) {
tail = task->prev;
tail->next = NULL;
} else {
TCB *after = task->next;
TCB *before = task->prev;
after->prev = before;
before->next = after;
}

count–;
free(task);
}
[/code]

Queue *q;

What does q point to?

  q->QueueInsert(NULL, blinking);

You just derreferenced a NULL pointer. The Arduino can't throw exceptions, so this simply did nothing.

v1t0ry:
I try to implement a doubly linked-list that holds task control blocks (TCBs), each of which contains a pointer to function and a void pointer.

What a complexity!

Why do you need a doubly linked-list, dynamically created at runtime?

Whay can't you use just a static "array of struct", which is fixed at compile time, each array element holding a function pointer and a data pointer, and you call the current function by an index in the array?

Could the CALLING syntax be ?

(currentTask->function)(currentTask->data);

Also,
Did you DEBUG your QueueInsert() function?
Does it actually set Head and Tail properly?

OP: Your class absolutely must have a constructor.

PaulS:
OP: Your class absolutely must have a constructor.

Does a Queue object ever get created ?

Does this ...

Queue *q;

actually create a Queue Object or
just define the *q variable, with a NULL value?

Does this ... actually create a Queue Object or

No, it does not. It defines a pointer to a Queue object, and initializes the pointer to NULL.

jurs:
What a complexity!

Why do you need a doubly linked-list, dynamically created at runtime?

Whay can't you use just a static "array of struct", which is fixed at compile time, each array element holding a function pointer and a data pointer, and you call the current function by an index in the array?

It is one of my assignments. I already use the array the previous one and now it is required to use doubly linked-list.

PaulS:

Queue *q;

What does q point to?

  q->QueueInsert(NULL, blinking);

You just derreferenced a NULL pointer. The Arduino can't throw exceptions, so this simply did nothing.

Thank you very much! I change the code

Queue *q = new Queue();
TCB *currentTask = new TCB();

and it works correctly :slight_smile: