I'm having a problem with pointers. Basically I have a struct which works as a linked list queue Pcb below.
struct pcb {
pid_t pid; // system process ID
char * args[MAXARGS]; // program name and args
int arrivaltime;
int remainingcputime;
struct pcb * next; // links for Pcb handlers
int priority, memalloc, res1, res2, res3, res4, status;
};
typedef struct pcb Pcb;
typedef Pcb * PcbPtr;
Now you can see I've typedef'ed the Pcb pointer as PcbPtr, meaning that PcbPtr is a pointer right?
Then I implemented these functions to add a PcbPtr to the queue, depending on its priority:
PcbPtr enqPcb(PcbPtr headofQ, PcbPtr process){
PcbPtr c = headofQ;
if (!headofQ) {
headofQ = process;
return headofQ;
}
while (c->next) {
c = c->next;
}
c->next = process;
return headofQ;
}
void priEnq(PcbPtr f1, PcbPtr f2, PcbPtr f3, PcbPtr a) {
int pri = a->priority;
if (pri == 3)
enqPcb(f3, a);
else if(pri == 2)
enqPcb(f2, a);
else
enqPcb(f1, a);
return;
}
but it's not changing the object I'm pointing to (i.e. headf1 in this case:)
PcbPtr headi;
PcbPtr headf1; //priority 1
PcbPtr headf2; //priority 2
PcbPtr headf3; //priority 3
...
priEnq(headf1, headf2, headf3, headi);
so its as if I'm passing another object as the parameter. When I don't use priEnq(), it adds to the list just fine.
Any ideas what I'm doing wrong? Any help is much appreciated
PcbPtr enqPcb(PcbPtr *headofQ, PcbPtr process){
PcbPtr c = *headofQ;
PcbPtr d = c;
if (!*headofQ) {
*headofQ = process;
return *headofQ;
}
while (c->next) {
c = c->next;
}
c->next = process;
return headofQ;
}
void priEnq(PcbPtr *f1, PcbPtr *f2, PcbPtr *f3, PcbPtr a) {
int pri = a->priority;
if (pri == 3)
enqPcb(f3, a);
else if(pri == 2)
enqPcb(f2, a);
else
enqPcb(f1, a);
return;
}
PcbPtr headi;
PcbPtr headf1; //priority 1
PcbPtr headf2; //priority 2
PcbPtr headf3; //priority 3
...
priEnq(&headf1, &headf2, &headf3, headi);
If I understand your problem correctly, the caller of priEnq has pointers to the queues, and wants those pointers updated if the function changes the head of the queue.
The problem is that you're passing the pointers by value. If you want the called function to modify the caller's values, then you must pass by reference, ie, a pointer to the pointer you want updated. In code:
PcbPtr enqPcb(PcbPtr *headofQ, PcbPtr process){
PcbPtr* c = headofQ;
if (!*headofQ) {
*headofQ = process;
return *headofQ;
}
while (c->next) {
c = c->next;
}
c->next = process;
return headofQ;
}
void priEnq(PcbPtr *f1, PcbPtr *f2, PcbPtr *f3, PcbPtr a) {
int pri = a->priority;
if (pri == 3)
enqPcb(f3, a);
else if(pri == 2)
enqPcb(f2, a);
else
enqPcb(f1, a);
return;
}
PcbPtr headi;
PcbPtr headf1; //priority 1
PcbPtr headf2; //priority 2
PcbPtr headf3; //priority 3
...
priEnq(&headf1, &headf2, &headf3, headi);
By passing the addresses of your queue pointers, you allow priEnq to modify your pointers, rather than just its own copies of them.
Also, as sarnold mentioned, you might want to consider an array of queue pointers for readability and maintainability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With