ISR executes even though an interrupt is not triggered I am trying to implement a function queue scheduling system. INT1 is connected to a button and int1task causes an LED to flash.

typedef void (*funcptr)(void);
TPrioQueue *queue = NULL;

void int1ISR() {
  if (debounce(&amp;int1time)) // Checks if the interrupt is caused by switch bouncing
    enq(queue, (void*) int1task, 1);
}


Next, I execute the function in loop() by:

typedef void (*funcptr)(void);

void loop(){
  funcptr func = (funcptr) deq(queue);
  if (func != NULL)
    (*func)(); // Stuck in a loop
}


For some reason, the LED keeps flashing even though I have not pressed the button. Why does this happen?

When I remove the line below, the ISR works properly.

enq(queue, (void*) int1task, 1)


The relevant sections of the code:

int debounce(unsigned long *debTimer) {
  unsigned long tmp = *debTimer;
  unsigned long currTime = millis();

  if ((currTime-tmp) &gt; 500){
    *debTimer = currTime;
    return 1;
  }
  else
    return 0;
}

// Flashes LED at pin 6 five times at 2 Hz
void int1task(){
  for(int i=0; i&lt;5; i++){
    digitalWrite(6, HIGH);
    delay(250);
    digitalWrite(6, LOW);
    delay(250);
  }
}

void setup() {
  pinMode(6, OUTPUT);
  attachInterrupt(1, int1ISR, RISING);
  Serial.begin(115200);
}


Code I used for the queue

Here is the schematic I am using:
After checking the queue functions that you use in your sketch, I see there is no protection against concurrent accesses in the enq and deq functions, which is a must-have if you use any of these functions from within an ISR.

I would suggest the simplest changes to these functions as follows:

void enq(TPrioQueue *queue, void *item, int priority)
{
    TPrioQEntry *newEntry=(TPrioQEntry *) malloc(sizeof(TPrioQEntry));

    if(newEntry != NULL)
    {
        newEntry-&gt;item=item;
        newEntry-&gt;prio=priority;
        newEntry-&gt;prev=NULL;
        newEntry-&gt;next=NULL;

        // Protect against concurrent accesses starting here
        uint8_t sreg = SREG;
        cli(); 
        if(queue-&gt;head==NULL)
            queue-&gt;head=newEntry;
        else
        {
            // Find insertion point.

            // First special case: Item at head has lower priority
            if(queue-&gt;head-&gt;prio &gt; newEntry-&gt;prio)
            {
                // Insert item at the start of the queue.
                newEntry-&gt;next=queue-&gt;head;
                queue-&gt;head-&gt;prev=newEntry;
                queue-&gt;head=newEntry;
            }
            else
            {
                // Find your insertion point
                TPrioQEntry *trav= queue-&gt;head;

                while(trav-&gt;next!=NULL &amp;&amp; trav-&gt;prio &lt; newEntry-&gt;prio)
                    trav=trav-&gt;next;

                newEntry-&gt;prev=trav;
                newEntry-&gt;next=trav-&gt;next;
                if(trav-&gt;next != NULL)
                    trav-&gt;next-&gt;prev=newEntry;

                trav-&gt;next=newEntry;
            }
        }

        queue-&gt;itemCount++;
        // Protect against concurrent accesses stops here
        SREG = sreg;
    }   
}

void *deq(TPrioQueue *queue)
{
    // Protect against concurrent accesses starting here
    uint8_t sreg = SREG;
    cli(); 
    // Return NULL if queue is empty
    if(queue-&gt;head == NULL)
    {
        // Protect against concurrent accesses stops here
        SREG = sreg;
        return NULL;
    }

    void *ret=queue-&gt;head-&gt;item;
    TPrioQEntry *tmp=queue-&gt;head;

    if(queue-&gt;head-&gt;next!=NULL)
        queue-&gt;head-&gt;next-&gt;prev=NULL;

    queue-&gt;head=queue-&gt;head-&gt;next;
    free(tmp);

    queue-&gt;itemCount--;

    // Protect against concurrent accesses stops here
    SREG = sreg;

    return ret;
}