Δημοσιεύτηκε: 20 Φεβ 2012, 15:50
από migf1
Α, ξέχασα να εξηγήσω μια σημαντική παρατήρηση σχετικά με τη χρήση της realloc() που ισχύει πάντα και όχι μονάχα για τον συγκεκριμένο κώδικα. Δεν πρέπει ποτέ να αναθέτουμε την τιμή επιστροφής της realloc() στον δείκτη που της έχουμε ζητήσει να κάνει realloc().

Δηλαδή, αν π.χ. έχουμε έναν δείκτη s που δείχνει σε μια έγκυρη περιοχή μνήμης και θέλουμε να αυξήσουμε ή να μειώσουμε το εύρος αυτής της περιοχής με realloc(), τότε χρησιμοποιούμε πρώτα έναν προσωρινό δείκτη για την τιμή επιστροφής της συνάρτησης.

Έστω πως έχουμε ένα ήδη δημιουργημένο c-string s με μέγιστο μήκος ίσο με 100 χαρακτήρες και θέλουμε να το αυξήσουμε σε 200 χαρακτήρες. Τότε, δεν κάνουμε απευθείας...

Κώδικας: Επιλογή όλων

s = realloc(s, 200 * sizeof(char));

αλλά χρησιμοποιούμε ένα προσωρινό δείκτη... αυτόν που ονομάζω try εγώ στο κώδικα του προηγούμενου ποστ. Οπότε έχουμε...

Κώδικας: Επιλογή όλων

try = realloc(s, 200 * sizeof(char));

Η επόμενη κίνηση είναι να ελέγξουμε αν απέτυχε το realloc()...
Κώδικας: Επιλογή όλων

if ( !try ) ...

Το σύνηθες όταν αποτυγχάνει η realloc() είναι να μην υπάρχει διαθέσιμο το συνεχόμενο κομμάτι μνήμης που ζητήσαμε. Όταν αποτυγχάνει η συνάρτηση μας επιστρέφει NULL, οπότε αν είχαμε κάνει...
Κώδικας: Επιλογή όλων

s = realloc(s, 200 * sizeof(char));

θα είχαμε χάσει την επαφή μας με την περιοχή μνήμης στην οποία έδειχνε ο s πριν την κλήση στην realloc() γιατί το s θα ήταν πλέον ίσο με NULL. Δεν θα είχαμε πια καν τρόπο να την κάνουμε free(s) εκείνη την περιοχή μνήμης... memory leak!

Ενώ τώρα που χρησιμοποιήσαμε τον try για την realloc(), ο s εξακολουθεί να δείχνει στη μνήμη που έδειχνε και πριν την κλήση της realloc() ;)
Αν θέλουμε μπορούμε να την κάνουμε κανονικά free(s) και να τερματίσουμε το πρόγραμμά μας με σήμα αποτυχίας προς το λειτουργικό. Ή μπορεί να θέλουμε να συνεχίσουμε να χρησιμοποιούμε το s με το μέγιστο μήκος που είχε πριν την κλήση της realloc(). Με λίγα λόγια, συνεχίζουμε να έχουμε πρόσβαση στη μνήμη που δείχνει ο s, ακόμα κι αν αποτύχει η realloc().

Αν από την άλλη μεριά πετύχει η realloc() το μόνο που χρειάζεται να κάνουμε για να αποκτήσουμε πρόσβαση στην διευρυμένη μνήμη, είναι να αναθέσουμε τον s εκεί που δείχνει ο try...

Κώδικας: Επιλογή όλων

try = realloc(s, 200 * sizeof(char));
if ( !try ) {
/* realloc() fail, decide here what you want to do with s */
}
else {
s = try;
}