Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeDefs and Pointers

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

SOLVED:

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);
like image 343
Milk Avatar asked Mar 11 '26 01:03

Milk


1 Answers

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.

like image 74
John Auld Avatar answered Mar 12 '26 17:03

John Auld



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!