0

I have a code that aims to enqueue a student into a queue of places available for a course. Here is the function I designed to do it:

int enqueue_CSC(student_info *CSC4352_queue, int *rear, student_info ToEnqueue)
{
    // The status is used to determine if the student should be added to the waitlist
    int status;
    // We check if the queue is full
    if (*rear == -1)
    {
        *rear = 0;
        CSC4352_queue[*rear] = ToEnqueue;
        status = 1;
    }
    if (*rear == 4)
    {
        printf("\tThere are no seats available for the Big Data Analytics (CSC 4352) course.\n");
        printf("\tYou will be added to the waiting list.\n");
        // status 0 means waitlist
        status = 0;
        return status;
    }
    // The queue is not full, increment the rear index and add the student;
    CSC4352_queue[++(*rear)] = ToEnqueue;
    // status 1 means successfully added
    status = 1;
    return status;
}

My waitlist function works just fine, but whenever I try to enqueue a student into the course queue, they get duplicated in the array, example:

Input: 101084 John

Printing the queue: 101084 John 101084 John

I have debugged the code and I am sure the queue bears a duplicate, but I do not know how to solve this issue.

Here's the print function:

void print_CSC4352_queue(student_info *CSC4352_queue, int rear, int front)
{

    printf("The content of the CSC 4352 queue is : \n");
    for (int i = 0; i < rear; i++)
    {
        printf("\t Student ID : %d\n", CSC4352_queue[i].ID);
        printf("\t Student name : %s\n", CSC4352_queue[i].name);
        printf("\n");
    }
    return;
}
user16217248
  • 3,119
  • 19
  • 19
  • 37
Réda
  • 15
  • 3
  • `free(ToEnqueue.ID)`? Did you allocate `ToEnqueue.ID` using `malloc`? Is `ToEnqueue.ID` even a pointer? Doesn't the compiler complain about that? You should `free` what you `malloc`, but nothing else. – Some programmer dude Apr 08 '23 at 21:52
  • maybe `if ... else if ... else` is what you want? If `rear==-1` you do `CSC4352_queue[*rear] = ToEnqueue;`, then later in the function you unconditionally do `CSC4352_queue[++(*rear)] = ToEnqueue;`. That's two adds in one function call for the right conditions. – yano Apr 08 '23 at 21:52
  • 1
    Also, the problem might not be the enqueue function, but the print function? Please create a proper [mre] to show us. – Some programmer dude Apr 08 '23 at 21:53
  • 1
    @yano There's a `return` in between. – Some programmer dude Apr 08 '23 at 21:53
  • @Someprogrammerdude ah, indeed there is, missed it, thanks. – yano Apr 08 '23 at 21:54
  • 1
    And these kinds of problems are usually solved by [*debugging*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) your programs. For example by using a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to step through the code line by line, while monitoring variables and their values, to see what happens. – Some programmer dude Apr 08 '23 at 21:55
  • @Someprogrammerdude I've edited my post, if you can please check the new enqueue_CSC function as well as the print one as you requested – Réda Apr 08 '23 at 21:59
  • 1
    That print function will actually print one *less* element from the array. When you add the first element, you set `rear` to `0`. And the loop have the condition `i < rear`. Now what happens when both `i` and `rear` are `0`? – Some programmer dude Apr 08 '23 at 22:07
  • 1
    And we still need a proper [mre] to be able to help you debug. Together with actual input (preferably hard-coded) and the actual output (that matches the code you show). – Some programmer dude Apr 08 '23 at 22:09
  • That's not a problem I encoutered thankfully, when I enter just one student it prints that only one, the problem occurs when I start adding more students in the queue, then the first one duplicates. – Réda Apr 08 '23 at 22:09
  • I don't know how to do the minimal reproductible example, i'm new to this. I'll just figure it out by myself, thanks for the help. – Réda Apr 08 '23 at 22:10
  • 1
    Create a simple `main` function that creates two dummy `student_info` structure objects, initialized with sample data. Call the enqueue function twice, passing each of the structures each time. Then call the print function. Thar would be your [mre]. If it doesn't replicate your problem, then it's in some other code. – Some programmer dude Apr 08 '23 at 22:21
  • In the first code you posted, there was a `return` in the `if (*rear == -1)` case. Why did you remove it in your edit? Was it not there in the real code? Is the code you show now as close to a [mre] as you want to go? Is it the actual code you build and run to give you the problem? Why not show us a *proper* example as I described above? – Some programmer dude Apr 09 '23 at 10:26

1 Answers1

0

If the queue is empty (I assume):

        if (*rear == -1) {
                  *rear = 0;
                  CSC4352_queue[*rear] = ToEnqueue;
        }

then you write the record a second time at position 1:

    CSC4352_queue[++(*rear)] = ToEnqueue;

I don't have a way of testing your snippet of code but what reworking it to this?

#define STATUS_SUCCESS 1
#define STATUS_FAIL 0
#define EMPTY -1
#define CAPACITY 4

int enqueue_CSC(student_info *CSC4352_queue, int *rear, student_info ToEnqueue) {
    if (*rear == CAPACITY) {
        printf("\tThere are no seats available for the Big Data Analytics (CSC 4352) course.\n");
        printf("\tYou will be added to the waiting list.\n");
        return STATUS_FAIL;
    }
    *rear = *rear == EMPTY ? 0 : ++(*rear);
    CSC4352_queue[*rear] = ToEnqueue;
    return STATUS_SUCCESS;
}

If you have the option swap the status values and just use stdlib.h's EXIT_SUCCESS and EXIT_FAILURE instead.

If you redefine *rear to be the next place where you want to write data then you don't need to a special case for -1:

    if(*rear + 1 == CAPACITY) {
        // ...
    }
    CSC4352_queue[(*rear)++] = ToEnqueue;
    // ...
Allan Wind
  • 23,068
  • 5
  • 28
  • 38