PDA

View Full Version : [C++] Coda circolare e operatore modulo


Albi89
06-04-2008, 22:31
Salve a tutti!
Sto cercando di implementare una coda statica.
La coda, di tipo circolare, soffre di un bug curioso (probabilmente dovuto a mie inesperienze con le precedenze degli operatori) che non sono riuscito a risolvere.

In particolare, nell'implementazione statica che ho realizzato sto usando un array, c.queue, di 10 elementi. La costante MAX_ELEM che appare nel codice è appunto uguale a 10; come è facile intuire, c.num_elem è il numero di elementi contenuti nella coda e c.top è l'indice che uso per indicare la testa della coda, su cui viene fatto l'inserimento.

int push(Coda& c, const int e) {
if (!full(c)) {

c.queue[c.top] = e;
c.top = (c.top++)%MAX_ELEM; //?!?!?
c.num_elem++;

return 0;
} else return 1;

Nel caso particolare, se provo ad inserire un elemento e poi a leggerlo subito, eliminandolo, i due indici di testa e di coda si appaiano (nella fattispecie si appaiano ad 1), mentre c.num_elem è ovviamente pari a 0.

Ora, se inserisco 8 elementi, avrò ovviamente un riempiemnto di 8 e c.top uguale a 9.
La cosa curiosa avviene all'esecuzione successiva: col debugger ho notato che al rigo c.top = (c.top++)%MAX_ELEM, c.top prende il valore 10!

Non capisco, c.top++ è uguale a 10 e MAX_ELEM uguale a 10, il resto della divisione intera dovrebbe essere 0!

All'esecuzione successiva poi, come dovrebbe essere, c.top++ è 11 e c.top prende valore 1, ma ormai il mio indice 0 è stato saltato, ed ho sovrascritto un'area di memoria che è occupata dal mio riempimento... provocando guai immani!

Grazie a chi potrà aiutarmi!

cionci
07-04-2008, 00:34
Questo perché c.top++ fa il post incremento.
Lo devi scrivere come ++c.top.
Inoltre ti consiglio di scrivere la condizione di coda piena diversamente:

int push(Coda& c, const int e) {
if (full(c)) {
return 1
}
c.queue[c.top] = e;
c.top = (++c.top)%MAX_ELEM; //?!?!?
c.num_elem++;
return 0;
}

Albi89
07-04-2008, 15:01
Questo perché c.top++ fa il post incremento.
Lo devi scrivere come ++c.top.
Inoltre ti consiglio di scrivere la condizione di coda piena diversamente:

int push(Coda& c, const int e) {
if (full(c)) {
return 1
}
c.queue[c.top] = e;
c.top = (++c.top)%MAX_ELEM; //?!?!?
c.num_elem++;
return 0;
}

Grazie mille per la risposta!
Effettivamente stamattina in treno ho perso il foglio, l'ho guardato e mi stavo mettendo le mani nei capelli... non so come ho fatto a non pensarci ieri sera... mi sono lasciato "sedurre" da un errore di stampa (un manuale di programmazione riportava la versione con c.top++) e avevo perso d'occhio l'incremento :sofico:

A proposito della condizione di coda piena, come mai mi consigli di invertire il controllo?

cionci
07-04-2008, 15:10
Solo per questione di leggibilità ;)

Albi89
07-04-2008, 17:22
Solo per questione di leggibilità ;)

Ok, capisco, effettivamente fa ballare un po' gli occhi e il ! sfugge sempre :D