τι περιέχει αυτό το κεφάλαιο...
Κατανομή χώρου με την malloc
Η συνάρτηση malloc κατανέμει χώρο δυναμικά. Βολεύει παρα πολύ όταν χρησιμοποιούμε και πίνακες γιατί έχουμε την δυνατότητα να δημιουργήσουμε την διάσταση του πίνακα όταν θελήσουμε στην διάρκεια του προγράμματος, αντίθετα με τον "κλασικό" τρόπο που οι διαστάσεις του πίνακα είναι ήδη ορισμένες στην αρχή και μένουν αμετάβλητες κατα την διάρκεια του προγράμματος(στατικός πίνακας)!
Ο κώδικας που χρειάζεται για να το κάνουμε αυτό είναι ο εξής:
- Κώδικας: Επιλογή όλων
char *buf;
int n;
buf = (char *)malloc(n*sizeof(char));
Στην ουσία, ορίζουμε έναν Pointer χαρακτήρα και του λέμε κοίταξε να δεις, εσύ θα πας και θα δεσμεύσεις n bytes από τη μνήμη. Επιπλέον, του λέμε πως θέλουμε συγκεκριμένα η μνήμη που δεσμεύουμε να είναι για char. Δεν είναι κάτι τρομερό!
Αφού δημιουργήσουμε τον χώρο (στην πραγματικότητα τα bytes που θέλουμε), θα είναι καλό να ακολουθήσει ένας έλεγχος, όπου θα καταλαβαίνουμε αν κατανεμήθηκε σωστά ή υπήρξε κάποιο σφάλμα (error), που συνηθως θα εκτύπωνεται στην οθόνη μας ως segmentation fault.
- Κώδικας: Επιλογή όλων
if(buf == NULL){
printf("Error in allocating memory.\n");
exit(1);
}else{
printf("Successful allocation.\n");
} /* και συνεχίζουμε κανονικά τον κώδικά μας! */
Για παράδειγμα, θα προσπαθήσουμε να κατανέμουμε 50 bytes χώρου(δεν έχει τόσο μεγάλη σημασία το ποσό) με την χρήση της malloc.
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *buf;
buf=(char *)malloc(50*sizeof(char));
if(buf == NULL){
printf("Not enough memory to allocate buffer.\n");
exit(1);
}
printf("String was successfully allocated.\n");
return 0;
}
//Output: String was successfully allocated
Κατανομή χώρου με την calloc
Η συνάρτηση calloc επίσης κατανέμει το χώρο δυναμικά. Όπως και η malloc έτσι και συτή βολεύει παρα πολύ όταν χρησιμοποιούμε και πίνακες γιατί έχουμε την δυνατότητα να δημιουργήσουμε την διάσταση του πίνακα όταν θελήσουμε στην διάρκεια του προγράμματος, αντίθετα με τον "κλασικό" τρόπο που οι διαστάεις του πίνακα είναι ήδη ορισμένες στην αρχή και μένουν αμετάβλητες κατα την διάρκεια του προγράμματος. However, η calloc έχει την επιπλέον ιδιότητα να μηδενίζει τον πίνακα αυτόματα αντίθετα με την malloc που απλά τον δημιουργεί. Συνεπως, εάν εκτυπώσουμε έναν πίνακα δημιουργημένο απο calloc και χωρίς να του έχουμε δώσει τιμές θα εκτυπώσει μηδενικά ενώ στην malloc θα εκτυπώσει σκουπίδια!

έγραψε:Προσέξτε την διαφορά με την malloc!
- Κώδικας: Επιλογή όλων
char *buf;
int n;
buf = (char *)calloc(n, sizeof(char));
έγραψε:Θα ήταν και εδώ σωστό να κάνουμε έναν έλεγχο εγκυρότητας όπως και παραπάνω. Ο κώδικας είναι ο ίδιος και δεν αλλάζει τίποτα.
Για παράδειγμα, θα προσπαθήσουμε να κατανέμουμε 50 bytes χώρου(δεν έχει τόσο μεγάλη σημασία το ποσό) με την χρήση της calloc.
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *ptr;
ptr=(int *)calloc(50,sizeof(int));
if(ptr == NULL){
printf("Allocation error.\n");
}
printf("Succcesfull allocation.\n");
}
Κατανομή χώρου με την realloc
Σε αντίθεση με τις άλλες δύο συναρτήσεις η realloc μας επιτρέπει να μεταβάλουμε το μέγεθος του πίνακα καθώς τρέχει το πρόγραμμα μας. Αυτό χρειάζεται σε περιπτώσεις που το αρχικό μέγεθος είναι μικρό σε σχέση με τα δεδομένα που αποθηκεύουμε και καταλήγουμε σε "segmentation fault". Να σημειώσω πως όταν θα χρησιμοποιήσετε την calloc θα πρέπει να έχετε κατανέμει δυναμικά τον χώρο χρησιμοποιώντας την malloc/calloc. Χρησιμοποιείτε ως εξής:
- Κώδικας: Επιλογή όλων
int *ptr, *buf, n;
buf = (int *)calloc(ptr, n*sizeof(int));
//ptr είναι ο παλιός πίνακας
//buf είναι ο καινούριος πίνακας με τις νέες διαστάσεις
Για παράδειγμα,
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
int main(void){
int *ptr;
//ptr είναι ο παλιός πίνακας
//buf είναι ο καινούριος πίνακας με τις νέες διαστάσεις
int *buf;
ptr = (int *)calloc(50,sizeof(int));
if(ptr == NULL){
printf("Allocation error.\n");
}else{
printf("Succcesfull allocation.\n");
}
buf = (int *)realloc(ptr,100*sizeof(int));
if(buf == NULL){
printf("Allocation error.\n");
}else{
printf("Succcesfull allocation (enlarge).\n");
}
}
Αποδέσμευση χώρου με την free
Χρησιμοποιώντας κάθε συνάρτηση απο τις παραπάνω θα έχει ως συνέπεια την δέσμευση κάποιων bytes απο την μνήμη σας. Κάποιο τέτοιο βέβαια θα είναι"φανερό" μόνο αν ο υπολογιστής που δουλεύετε είναι παλιός με πολύ μικρή μνήμη. Όλοι πλέον οι υπολογιστές είναι μεγάλης χωριτηκότητας μνήμης οπότε η χρήση της συνάρτησης δεν θα πρέπει να σας απασχολεί πολύ. Όμως, ένας σωστός προγραμματιστής όταν ξεκινά ένα πρόγραμμα θα πρέπει αν το τελειώνει σωστά. Οπότε, καλό είναι να γράψετε άλλη μια γραμμή.
- Κώδικας: Επιλογή όλων
char *buf;
free(buf);
έγραψε:Η συνάρτηση free ελευθερώνει τα Bytes που χρησιμοποιήθηκαν!
Για παράδειγμα,
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *buf;
buf=(char *)malloc(50*sizeof(char));
if(buf == NULL){
printf("Not enought memory to allocate buffer.\n");
exit(1);
}
printf("String was successfully allocated.\n");
free(buf);
if(buf == NULL){
printf("Successfull free.\n");
}
return 0;
}
Μπορείτε να το βρείτε και εδώ: http://www.freewebs.com/cpptutorial/spaceallocation.htm
ΚΑΛΗ ΣΥΝΕΧΕΙΑ!!! - ΓΙΑ ΑΠΟΡΙΕΣ ΡΩΤΗΣΤΕ!!!