0

following is my code.. I have implemented Process class and taking in input in an array of Process objects. Then, in my Priority_Scheduling Class, I am calling a sorting function for Priority sort that sorts the array according to the value of priority of all the Process objects...

Interestingly, I am getting garbage value for obj[3] but for all other indexes (1 - 4), it gives a valid value. Due to this garbage value, priority sort performs an abnormal sorting and code doesn't work. Can anyone help identify the error, please?

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Process;
class Priority_Scheduling;
struct node
{
    int data;
    node* next;
};
struct Process_Type // To store average times for all the processes. 
{
    string process_name;
    float avg_turnaround_time;
    float avg_waiting_time;
};
class Queue
{
    node* front;
    node* rear;
public:
    Queue();
    bool isEmpty();
    void dequeue();
    void enqueue(int &);
    int peek();
};
class Process
{
    int id;
    static int count; // Count will maintain the record of total processes created. 
    int burst_time;
    int stored_burst_time; // To keep the original value of burst time intact. 
    int arrival_time;
    int completion_time;
    int turnaround_time;
    int waiting_time;
    int priority;
    bool has_finished; // To check whether process has finished execution or not
public:
    friend class Priority_Scheduling;
    Process() :id(count) { completion_time = turnaround_time = waiting_time = 0; count++; has_finished = false; priority = 0; }
    // Every process will have a unique Process ID as assigned by count...  
    void input();
    // Set and Get Functions. 
    int get_t() { return turnaround_time; }
    int get_w() { return waiting_time; }
    int getid() { return id; }
    int get_bt() { return burst_time; }
    int get_ct() { return completion_time; }
    int get_at() { return arrival_time; }
    int get_sbt() { return stored_burst_time; }
    void set_bt(int &a) { burst_time = a; }
    void set_at(int &a) { arrival_time = a; }
    void set_ct(int &a) { completion_time = a; }
    void set_t(int &a) { turnaround_time = a; }
    void set_w(int &a) { waiting_time = a; }
    bool get_finished() { return has_finished; }
    void set_finished(bool a) { has_finished = a; }
    int get_priority() { return priority; }
    void Display();
    void Display_Before();
    Process(const Process &);
};
class Priority_Scheduling
{
    int total_time;
public:
    void sort();
    bool check();
    void priority_sort();
    void Calculate(Queue &);
    void algorithm();
};
int Process::count = 0;
int time_slice, num;
Process_Type p_type[4];
Process *obj = NULL;
Queue Ready_Queue[4];
void input();
int main()
{
    input();
    Priority_Scheduling sjf;
    cout << endl << endl << setw(15) << "Process ID" << setw(15) << "Arrival Time" << setw(15) << "Burst Time" << setw(15) << "Priority" << endl
        << "------------------------------------------------------------------" << endl;
    for (int i = 0; i < num; i++)
        obj[i].Display_Before();
    sjf.algorithm();


    // Round Robin Algorithm is used as a driver algorithm for the implementation of question.

    // Printing Before Calculation



    // Printing After Calculation
    cout << endl << endl << setw(15) << "Process ID" << setw(15) << "Arrival Time" << setw(15) << "Burst Time" << setw(15) << "Turnaround" << setw(15) << "Waiting Time" << endl
        << "------------------------------------------------------------------" << endl;
    for (int i = 1; i < num; ++i)
    {
        for (int j = 0; j < num - i; ++j)
            if (obj[j].getid() > obj[j + 1].getid())
                swap(obj[j], obj[j + 1]);
    }
    for (int i = 0; i < num; i++)
        obj[i].Display();
    cout << endl << endl;
    cout << endl;
    system("pause");

    return 0;
}

void input()
{
    do
    {
        cout << "Enter Number of Processes: ";
        cin >> num;
    } while (num < 1);
    obj = new Process[num];
    for (int i = 0; i < num; i++)
        obj[i].input();
}

void Process::Display()
{
    cout << setw(15) << id << setw(15) << arrival_time << setw(15) << stored_burst_time << setw(15) << turnaround_time << setw(15) << waiting_time;
    cout << endl;
}
void Process::Display_Before()
{
    cout << setw(15) << id << setw(15) << arrival_time << setw(15) << stored_burst_time << setw(15) << priority << endl;
}
void Process::input()
{
    cout << "Process: " << id << endl
        << "Enter Arrival Time: "; cin >> arrival_time;
    cout << "Enter Burst Time: "; cin >> burst_time;
    stored_burst_time = burst_time;
    cout << "Enter Priority: "; cin >> priority;
}

// --------------------Priority CLASS ------------------------------------
void Priority_Scheduling::sort()
{
    int j;
    for (int i = 1; i < num; ++i)
    {
        for (j = 0; j < num - i; ++j)
            if (obj[j].get_at() > obj[j + 1].get_at())
                swap(obj[j], obj[j + 1]);
    }
}
void Priority_Scheduling::priority_sort()
{
    cout << "Enter" << endl; // Checking if the program has entered or not. 
    int j;
    for (int i = 1; i < num; ++i)
    {
        for (j = 0; j < num - 1; ++j)
        {
            cout << "j: " << j << "     obj[j].p: " << obj[j].priority << endl
                << "j+1: " << j << "    obj[j+1].p: " << obj[j + 1].priority << endl; // Printing out values of j and j+1
            if (obj[j].priority > obj[j + 1].priority)
                swap(obj[j], obj[j + 1]);
        }
    }
}
bool Priority_Scheduling::check()
{
    for (int i = 0; i < num; i++)
        if (obj[i].get_finished() == false)
            return false;
    return true;
}
void Priority_Scheduling::algorithm()
{
    for (int i = 0; i < num; i++)
        cout << obj[i].getid() << " "; // PRINTING OUT IDS OF ALL PROCESSES AS TEST
    total_time = 0;
    cout << endl;
    sort();
    priority_sort();
    for (int i = 0; i < num; i++)
        cout << obj[i].priority << " "; // Printing out values of Priority of all processes after sorting. This gives garbage values
    while (!check())
    {
        for (int i = 0; i < num; i++)
        {
            if (obj[i].get_at() <= total_time) // Initially, only those processes are inserted whose arrival time is zero.
                if (obj[i].get_finished() == false)
                    Ready_Queue[2].enqueue(i);  // Inserting Process IDs into the Queue for Priority_Scheduling
        }
        if (!(Ready_Queue[2].isEmpty()))
            Calculate(Ready_Queue[2]);
    }
    for (int i = 0; i < num; i++)
    {
        p_type[2].avg_turnaround_time += obj[i].get_t();
        p_type[2].avg_waiting_time += obj[i].get_w();
    }
    p_type[2].avg_turnaround_time = p_type[2].avg_turnaround_time / num;
    p_type[2].avg_waiting_time = p_type[2].avg_waiting_time / num;
    cout << "Average Turnaround Time: " << p_type[2].avg_turnaround_time << endl
        << "Average Waiting Time: " << p_type[2].avg_waiting_time << endl;
}
void Priority_Scheduling::Calculate(Queue &Ready_Queue)
{
    int temp = Ready_Queue.peek();
    Ready_Queue.dequeue();
    int b = total_time + obj[temp].get_sbt();
    obj[temp].set_ct(b);
    total_time += obj[temp].get_sbt();
    b = obj[temp].get_ct() - obj[temp].get_at();
    obj[temp].set_t(b);
    b = obj[temp].get_t() - obj[temp].get_sbt();
    obj[temp].set_w(b);
    obj[temp].set_finished(true);
    while (!(Ready_Queue.isEmpty()))
        Ready_Queue.dequeue();
}

// ------------------- QUEUE CLASS IMPLEMENTATION ---------------------------

Queue::Queue() { front = NULL; rear = NULL; }
bool Queue::isEmpty()
{
    if (!front)
        return true;
    return false;
}
int Queue::peek() { return front->data; }
void Queue::enqueue(int &d)
{
    node* temp = new node;
    temp->data = d;
    temp->next = NULL;
    if (isEmpty())
    {
        front = temp;
        rear = temp;
        return;
    }
    rear->next = temp;
    rear = temp;
}
void Queue::dequeue()
{
    if (isEmpty())
    {
        cout << "Nothing to delete";
        return;
    }
    node* temp = front;
    front = front->next;
    free(temp);
}

Process::Process(const Process &Process_obj)
{
    this->arrival_time = Process_obj.arrival_time;
    this->burst_time = Process_obj.burst_time;
    this->completion_time = Process_obj.completion_time;
    this->id = Process_obj.id;
    this->stored_burst_time = Process_obj.stored_burst_time;
    this->turnaround_time = Process_obj.turnaround_time;
    this->waiting_time = Process_obj.waiting_time;
    this->has_finished = Process_obj.has_finished;
}

Following is a sample inputs I gave to my code.. and this is what I got,

Enter Number of Processes: 5
Process: 0
Enter Arrival Time: 0
Enter Burst Time: 3
Enter Priority: 3
Process: 1
Enter Arrival Time: 1
Enter Burst Time: 6
Enter Priority: 4
Process: 2
Enter Arrival Time: 3
Enter Burst Time: 1
Enter Priority: 9
Process: 3
Enter Arrival Time: 2
Enter Burst Time: 2
Enter Priority: 7
Process: 4
Enter Arrival Time: 4
Enter Burst Time: 4
Enter Priority: 8


     Process ID   Arrival Time     Burst Time       Priority
------------------------------------------------------------------
              0              0              3              3
              1              1              6              4
              2              3              1              9
              3              2              2              7
              4              4              4              8
0 1 2 3 4 // Process IDs.
Enter // indication than program has entered sorting function
j: 0     obj[j].p: 3 // For obj[0], prioriy value is good
j+1: 0    obj[j+1].p: 4 // for index 1, it's also good
j: 1     obj[j].p: 4 // for index = 1, again good
j+1: 1    obj[j+1].p: 7 // for index = 2, again good
j: 2     obj[j].p: 7 // for index = 2, again good
j+1: 2    obj[j+1].p: -858993460 // NOW HERE IS THE PROBLEM, for INDEX = 3
j: 3     obj[j].p: -858993460
j+1: 3    obj[j+1].p: 8 // Interestingyly, value is good for INDEX = 4 also. 
j: 0     obj[j].p: 3
j+1: 0    obj[j+1].p: 4
j: 1     obj[j].p: 4
j+1: 1    obj[j+1].p: -858993460
j: 2     obj[j].p: -858993460
j+1: 2    obj[j+1].p: -858993460
j: 3     obj[j].p: -858993460
j+1: 3    obj[j+1].p: 8
j: 0     obj[j].p: 3
j+1: 0    obj[j+1].p: -858993460
j: 1     obj[j].p: -858993460
j+1: 1    obj[j+1].p: -858993460
j: 2     obj[j].p: -858993460
j+1: 2    obj[j+1].p: -858993460
j: 3     obj[j].p: -858993460 // as a result, all values get garbaged

I have added small notes as where the actual problem is occuring in the output. Please help if you can, thank you.

  • [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/5910058) – Jesper Juhl May 16 '20 at 15:47
  • Why don't you initialize your variables? – Jesper Juhl May 16 '20 at 15:49
  • I tried using debugger, still couldn't figure out why it was giving garbage value at obj[3]. and I have initialized the priority variable with "0" in the constructor of class. the priority is working fine..... It's the problem with the array. For some reason, it is going out of bound and hence, giving a garbage error (as far as I understand) – Matt Malcom May 16 '20 at 15:55
  • 1
    `for (int i = 1; i < num; ++i)` -- Why is this loop starting at `1`? Shouldn't it start from `0`? Also this: `static int count; // Count will maintain the record of total processes created` is misleading and this type of code can give wrong results. If you want to keep track of the "real' number of items created, supply a CreateProcess() `static` member function that creates Processes, and increment the number in that function. – PaulMcKenzie May 16 '20 at 16:16
  • @PaulMcKenzie No, I think that doesn't change anything... And even after having changed it to 0, it still gives the same values as given in the output I showed. – Matt Malcom May 16 '20 at 16:19
  • @PaulMcKenzie Ok... but I am not using it to keep the record of total processes created actually (the comment is a little misleading) I am only using it to assign the value to the Process ID.... Otherwise, the total processes created is stored in a global variable "num", which is inputted by the user at the start of program – Matt Malcom May 16 '20 at 16:21
  • 1
    You have a major bug in your copy constructor for `Process` -- how many member variables are there in `Process`, and how many member variables are you assigning to in your copy constructor? Also, why are you writing a copy constructor anyway? By overriding the compiler's default copy constructor, you just introduced yourself to a bug, or at the very least, a partial copy masquerading as an actual copy. – PaulMcKenzie May 16 '20 at 16:22
  • 1
    Also, why are you calling `free()` in a C++ program? You allocated with `new`, so it must be deallocated using `delete`, not `free()`. This is another bug. – PaulMcKenzie May 16 '20 at 16:31
  • Why do you say the problem occurs "for INDEX = 3"? When I look at your output, I see a problem at index 2. The reported priority at index 2 is `7`, but the entered priority was `9`. – JaMiT May 16 '20 at 16:57
  • PaulMcKenzie yes, copy constructor is a little bugged. I will fix that... Free() is simply a built in command that deletes the allocated memory. delete is a bit difficult to use @JaMiT It sorts the array before on the basis of Arrival Time and then calls the priority sort. (I tried removing the first sort as well but it gave the same problem) – Matt Malcom May 16 '20 at 17:24
  • @MattMalcom Where is the output showing that the state of the array after sorting based on arrival time? You have too many steps going on for effective debugging. A [mre] would eliminate the noise and focus on just the step where the problem is introduced. – JaMiT May 16 '20 at 17:27
  • @Matt "delete is a bit difficult to use" - that makes no sense. And in any case, regardless of how difficult it is, it's still the correct thing and anything else is a bug. – Jesper Juhl May 16 '20 at 17:56

0 Answers0