Και μιας και έχω όρεξη και λίγο διαθέσιμο χρόνο, δες Ηλία πως μπορείς να αντιμετωπίσεις με δυναμική διαχείριση μνήμης το πρόβλημα των immutable string ορισμάτων μιας συνάρτησης.
-
Μορφοποιημένος Κώδικας: Επιλογή όλων
-
char *s_dup2upper( char *s ) /* duplicate s & uppercase it */
{
char *snew = NULL;
/* sanity checks */
if ( !s )
return NULL;
if ( '\0' == *s )
return s;
/* δυναμική δημιουργία αντιγράφου του s */
snew = calloc( 1+strlen(s), sizeof(char) ); /* δέσμευση μνήμης, μεγέθους 1+strlen() chars */
if ( !snew )
return NULL; // out of memory
strcpy( snew, s );
/* "κεφαλοποίηση" του αντιγράφου */
for (char *cp=snew; (*cp = (char)toupper( (int)(*cp) ); cp++)
; /* void */
/* επιστροφή δείκτη στην αρχή του αντιγράφου */
return snew;
}
Η συνάρτηση αυτή δημιουργεί δυναμικά ένα αντίγραφο του s, το οποίο και "κεφαλοποιεί". Η τιμή επιστροφής της είναι ένας δείκτης στην αρχή του αντίγραφου, ενώ σε περίπτωση αποτυχίας επιστρέφει είτε NULL (αν το s ήταν ανύπαρκτο, δλδ NULL, ή αν η απέτυχε η δέσμευση μνήμης για το αντίγραφο) είτε έναν δείκτη στην αρχή του original s (αν το s ήταν κενό, δλδ s[0] = '\0' ).
Πλέον αλλάζει η λογική όπως την ξέρουμε με τα στατικά ορισμένα strings, και η κλήση της συνάρτησης γίνεται κάπως έτσι...
-
Μορφοποιημένος Κώδικας: Επιλογή όλων
-
int main( void )
{
char s[] = "This is our orignal s";
char *sdup = s_dup2upper(s); /* δημιουργία "κεφαλοποιημένου" αντιγράφου */
if ( !sdup ) {
puts( "out of memory" );
exit( EXIT_FAILURE);
}
puts( sdup ); /* τύπωμα του αντιγραφου */
free( sdup ); /* απελευθέρωση της μνήμης που έχει δεσμευτεί δυναμικά για το αντίγραφο */
exit( EXIT_SUCCESS );
}
Πλέον μπορούμε να εφαρμόσουμε την s_dup2upper() και σε immutable όρισμα, διότι πολύ απλά η συνάρτηση δεν δουλεύει πάνω του, αλλά σε ένα αντίγραφο που το δημιουργεί εσωτερικά, το τροποποιεί και μας το επιστρέφει.
Το τίμημα είναι πως χρησιμοποιούμε και 2η μεταβλητή που πρέπει να τη βάλουμε να δείχνει στο επιστρεφόμενο αντίγραφο, συν ότι στο τέλος πρέπει να απελευθερώσουμε χειροκίνητα (με το free() ) τη μνήμη που δεσμεύτηκε για το αντίγραφο.
ΥΓ. Δεν το έχω τσεκάρει αν τρέχει σωστά, το έγραψα απευθείας εδώ.