Δυναμική κατανομή μνήμης σε συναρτήσεις C: malloc (), calloc ()

Πίνακας περιεχομένων:

Anonim

Πριν μάθετε την κατανομή της δυναμικής μνήμης C, ας καταλάβουμε:

Πώς λειτουργεί η Διαχείριση μνήμης στο C;

Όταν δηλώνετε μια μεταβλητή χρησιμοποιώντας έναν βασικό τύπο δεδομένων, ο μεταγλωττιστής C εκχωρεί αυτόματα χώρο μνήμης για τη μεταβλητή σε μια ομάδα μνήμης που ονομάζεται στοίβα .

Για παράδειγμα, μια μεταβλητή float διαρκεί συνήθως 4 byte (σύμφωνα με την πλατφόρμα) όταν δηλωθεί. Μπορούμε να επαληθεύσουμε αυτές τις πληροφορίες χρησιμοποιώντας το μέγεθος του τελεστή όπως φαίνεται στο παρακάτω παράδειγμα

#include int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

Η έξοδος θα είναι:

 The size of float is 4 bytes 

Επίσης, ένας πίνακας με καθορισμένο μέγεθος εκχωρείται σε συνεχόμενα μπλοκ μνήμης, κάθε μπλοκ έχει το μέγεθος για ένα στοιχείο:

#include int main() { float arr[10];printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;} 

Το αποτέλεσμα είναι:

 The size of the float array with 10 element is 40

Όπως έχει μάθει μέχρι στιγμής, όταν δηλώνεται ένας βασικός τύπος δεδομένων ή ένας πίνακας, η μνήμη διαχειρίζεται αυτόματα. Ωστόσο, υπάρχει μια διαδικασία εκχώρησης μνήμης στο C, η οποία θα σας επιτρέψει να εφαρμόσετε ένα πρόγραμμα στο οποίο το μέγεθος του πίνακα δεν έχει αποφασιστεί μέχρι να εκτελέσετε το πρόγραμμά σας (χρόνος εκτέλεσης). Αυτή η διαδικασία ονομάζεται " Δυναμική κατανομή μνήμης ."

Σε αυτό το σεμινάριο, θα μάθετε-

  • Πώς λειτουργεί η Διαχείριση μνήμης στο C;
  • Δυναμική κατανομή μνήμης σε C
  • Λειτουργία C malloc ()
  • Η δωρεάν λειτουργία ()
  • Λειτουργία C calloc ()
  • calloc () έναντι malloc (): Βασικές διαφορές
  • C realloc () Λειτουργία
  • Δυναμικές συστοιχίες

Δυναμική κατανομή μνήμης σε C

Το Dynamic Memory Allocation είναι μη αυτόματη κατανομή και απελευθέρωση μνήμης σύμφωνα με τις ανάγκες προγραμματισμού σας. Η δυναμική μνήμη διαχειρίζεται και εξυπηρετείται με δείκτες που οδηγούν στον πρόσφατα εκχωρημένο χώρο μνήμης σε μια περιοχή που ονομάζουμε σωρός.

Τώρα μπορείτε να δημιουργήσετε και να καταστρέψετε μια σειρά στοιχείων δυναμικά κατά το χρόνο εκτέλεσης χωρίς προβλήματα. Συνοψίζοντας, η αυτόματη διαχείριση μνήμης χρησιμοποιεί τη στοίβα και το C Dynamic Memory Allocation χρησιμοποιεί το σωρό.

Η βιβλιοθήκη έχει λειτουργίες υπεύθυνες για τη διαχείριση δυναμικής μνήμης.

Λειτουργία Σκοπός
malloc () Εκχωρεί τη μνήμη του ζητούμενου μεγέθους και επιστρέφει το δείκτη στο πρώτο byte του εκχωρημένου χώρου.
calloc () Διαθέτει τον χώρο για στοιχεία ενός πίνακα Αρχίζει τα στοιχεία στο μηδέν και επιστρέφει ένα δείκτη στη μνήμη.
ρεαλόκ () Χρησιμοποιείται για την τροποποίηση του μεγέθους του χώρου μνήμης που είχε εκχωρηθεί προηγουμένως.
Ελεύθερος() Απελευθερώνει ή αδειάζει τον προηγουμένως εκχωρημένο χώρο μνήμης.

Ας συζητήσουμε τις παραπάνω λειτουργίες με την εφαρμογή τους

Λειτουργία C malloc ()

Η συνάρτηση C malloc () σημαίνει κατανομή μνήμης. Είναι μια συνάρτηση που χρησιμοποιείται για να κατανέμει δυναμικά ένα μπλοκ μνήμης. Διατηρεί χώρο μνήμης καθορισμένου μεγέθους και επιστρέφει το μηδενικό δείκτη που δείχνει στη θέση μνήμης. Ο δείκτης που επιστρέφεται είναι συνήθως άκυρος τύπου. Αυτό σημαίνει ότι μπορούμε να αντιστοιχίσουμε τη συνάρτηση C malloc () σε οποιονδήποτε δείκτη.

Σύνταξη malloc () Λειτουργία:

ptr = (cast_type *) malloc (byte_size);

Εδώ,

  • Το ptr είναι δείκτης του cast_type.
  • Η συνάρτηση C malloc () επιστρέφει ένα δείκτη στην εκχωρημένη μνήμη του byte_size.

Παράδειγμα malloc ():

Example: ptr = (int *) malloc (50)

Όταν εκτελεστεί με επιτυχία αυτή η δήλωση, δεσμεύεται χώρος μνήμης 50 byte. Η διεύθυνση του πρώτου byte του δεσμευμένου χώρου εκχωρείται στο δείκτη ptr του τύπου int.

Εξετάστε ένα άλλο παράδειγμα:

#include int main(){int *ptr;ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */if (ptr != NULL) {*(ptr + 5) = 480; /* assign 480 to sixth integer */printf("Value of the 6th integer is %d",*(ptr + 5));}}

Παραγωγή:

Value of the 6th integer is 480

  1. Παρατηρήστε ότι χρησιμοποιήθηκε το sizeof (* ptr) αντί για το sizeof (int) για να γίνει ο κώδικας πιο ισχυρός όταν η δήλωση * ptr τυποποιείται σε διαφορετικό τύπο δεδομένων αργότερα.
  2. Η κατανομή ενδέχεται να αποτύχει εάν η μνήμη δεν είναι επαρκής. Σε αυτήν την περίπτωση, επιστρέφει ένα δείκτη NULL. Επομένως, πρέπει να συμπεριλάβετε κωδικό για να ελέγξετε έναν δείκτη NULL.
  3. Λάβετε υπόψη ότι η εκχωρημένη μνήμη είναι συνεχόμενη και μπορεί να αντιμετωπιστεί ως πίνακας. Μπορούμε να χρησιμοποιήσουμε αριθμητική δείκτη για πρόσβαση στα στοιχεία του πίνακα και όχι με αγκύλες []. Σας συμβουλεύουμε να χρησιμοποιήσετε το + για να αναφερθείτε στα στοιχεία του πίνακα, επειδή με την αύξηση ++ ή + = αλλάζει τη διεύθυνση που έχει αποθηκευτεί από το δείκτη.

Η λειτουργία Malloc () μπορεί επίσης να χρησιμοποιηθεί με τον τύπο δεδομένων χαρακτήρων καθώς και περίπλοκους τύπους δεδομένων όπως δομές.

Η δωρεάν λειτουργία ()

Η μνήμη για μεταβλητές απενεργοποιείται αυτόματα κατά το χρόνο μεταγλώττισης. Στη δυναμική κατανομή μνήμης, πρέπει να αφαιρέσετε ρητά τη μνήμη. Εάν δεν γίνει, ενδέχεται να αντιμετωπίσετε σφάλμα μνήμης.

Η συνάρτηση free () καλείται για απελευθέρωση / αφαίρεση μνήμης σε C. Με την απελευθέρωση της μνήμης στο πρόγραμμά σας, καθιστάτε περισσότερο διαθέσιμο για χρήση αργότερα.

Για παράδειγμα:

#include int main() {int* ptr = malloc(10 * sizeof(*ptr));if (ptr != NULL){*(ptr + 2) = 50;printf("Value of the 2nd integer is %d",*(ptr + 2));}free(ptr);}

Παραγωγή

 Value of the 2nd integer is 50

Λειτουργία C calloc ()

Η συνάρτηση C calloc () σημαίνει συνεχόμενη κατανομή. Αυτή η λειτουργία χρησιμοποιείται για την εκχώρηση πολλαπλών μπλοκ μνήμης. Πρόκειται για μια δυναμική λειτουργία κατανομής μνήμης που χρησιμοποιείται για την κατανομή της μνήμης σε σύνθετες δομές δεδομένων, όπως πίνακες και δομές.

Η συνάρτηση Malloc () χρησιμοποιείται για την εκχώρηση ενός μπλοκ χώρου μνήμης ενώ το calloc () στο C χρησιμοποιείται για την εκχώρηση πολλαπλών μπλοκ χώρου μνήμης. Κάθε μπλοκ που εκχωρείται από τη συνάρτηση calloc () έχει το ίδιο μέγεθος.

Συνάρτηση calloc ()

ptr = (cast_type *) calloc (n, size);
  • Η παραπάνω δήλωση χρησιμοποιείται για την εκχώρηση n μπλοκ μνήμης του ίδιου μεγέθους.
  • Αφού εκχωρηθεί χώρος μνήμης, τότε όλα τα byte αρχικοποιούνται στο μηδέν.
  • Επιστρέφεται ο δείκτης που βρίσκεται στο πρώτο byte του εκχωρημένου χώρου μνήμης.

Όποτε υπάρχει σφάλμα κατά την εκχώρηση χώρου μνήμης όπως η έλλειψη μνήμης, τότε επιστρέφεται ένας μηδενικός δείκτης.

Παράδειγμα calloc ():

Το παρακάτω πρόγραμμα υπολογίζει το άθροισμα μιας αριθμητικής ακολουθίας.

#include int main() {int i, * ptr, sum = 0;ptr = calloc(10, sizeof(int));if (ptr == NULL) {printf("Error! memory not allocated.");exit(0);}printf("Building and calculating the sequence sum of the first 10 terms \ n ");for (i = 0; i < 10; ++i) { * (ptr + i) = i;sum += * (ptr + i);}printf("Sum = %d", sum);free(ptr);return 0;}

Αποτέλεσμα:

Building and calculating the sequence sum of the first 10 termsSum = 45

calloc () έναντι malloc (): Βασικές διαφορές

Ακολουθεί η βασική διαφορά μεταξύ malloc () Vs calloc () στο C:

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

Το μπλοκ μνήμης που εκχωρείται από ένα calloc () στο C αρχικοποιείται πάντα στο μηδέν, ενώ στο malloc συνάρτηση () στο C, περιέχει πάντα μια τιμή απορριμμάτων

C realloc () Λειτουργία

Χρησιμοποιώντας τη λειτουργία C realloc () , μπορείτε να προσθέσετε περισσότερο μέγεθος μνήμης στην ήδη εκχωρημένη μνήμη. Επεκτείνει το τρέχον μπλοκ αφήνοντας το αρχικό περιεχόμενο όπως είναι. realloc () στο C σημαίνει ανακατανομή της μνήμης.

Το realloc () μπορεί επίσης να χρησιμοποιηθεί για τη μείωση του μεγέθους της προηγουμένως εκχωρημένης μνήμης.

Σύνταξη του realloc () Λειτουργία:

ptr = realloc (ptr,newsize);

Η παραπάνω δήλωση εκχωρεί έναν νέο χώρο μνήμης με καθορισμένο μέγεθος στη μεταβλητή newsize. Μετά την εκτέλεση της λειτουργίας, ο δείκτης θα επιστρέψει στο πρώτο byte του μπλοκ μνήμης. Το νέο μέγεθος μπορεί να είναι μεγαλύτερο ή μικρότερο από την προηγούμενη μνήμη. Δεν μπορούμε να είμαστε σίγουροι ότι εάν το μπλοκ που έχει εκχωρηθεί πρόσφατα θα δείχνει στην ίδια θέση με εκείνη του προηγούμενου μπλοκ μνήμης. Αυτή η συνάρτηση θα αντιγράψει όλα τα προηγούμενα δεδομένα στη νέα περιοχή. Διασφαλίζει ότι τα δεδομένα θα παραμείνουν ασφαλή.

Παράδειγμα realloc ():

#include int main () {char *ptr;ptr = (char *) malloc(10);strcpy(ptr, "Programming");printf(" %s, Address = %u\n", ptr, ptr);ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new sizestrcat(ptr, " In 'C'");printf(" %s, Address = %u\n", ptr, ptr);free(ptr);return 0;} 

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

Δυναμικές συστοιχίες σε C

Ένας δυναμικός πίνακας στο C επιτρέπει στον αριθμό των στοιχείων να αυξάνεται ανάλογα με τις ανάγκες. Το C Dynamic array χρησιμοποιείται ευρέως στους αλγόριθμους επιστήμης υπολογιστών.

Στο ακόλουθο πρόγραμμα, έχουμε δημιουργήσει και αλλάξει το μέγεθος ενός δυναμικού πίνακα σε C

#include int main() {int * arr_dynamic = NULL;int elements = 2, i;arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocksfor (i = 0; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);elements = 4;arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elementsprintf("After realloc\n");for (i = 2; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);free(arr_dynamic);} 

Αποτέλεσμα του προγράμματος C Dynamic array στην οθόνη:

arr_dynamic[0]=0arr_dynamic[1]=1After reallocarr_dynamic[0]=0arr_dynamic[1]=1arr_dynamic[2]=2arr_dynamic[3]=3

Περίληψη

  • Μπορούμε να διαχειριστούμε δυναμικά τη μνήμη δημιουργώντας μπλοκ μνήμης όπως απαιτείται στο σωρό
  • Στο C Dynamic Memory Allocation, η μνήμη κατανέμεται κατά το χρόνο εκτέλεσης.
  • Η δυναμική κατανομή μνήμης επιτρέπει τον χειρισμό συμβολοσειρών και συστοιχιών των οποίων το μέγεθος είναι ευέλικτο και μπορεί να αλλάξει ανά πάσα στιγμή στο πρόγραμμά σας.
  • Απαιτείται όταν δεν έχετε ιδέα πόση μνήμη πρόκειται να καταλάβει μια συγκεκριμένη δομή.
  • Το Malloc () στο C είναι μια δυναμική συνάρτηση κατανομής μνήμης που σημαίνει κατανομή μνήμης που μπλοκάρει τη μνήμη με το συγκεκριμένο μέγεθος να αρχικοποιείται σε μια τιμή σκουπιδιών
  • Το Calloc () στο C είναι μια συνεχόμενη συνάρτηση κατανομής μνήμης που εκχωρεί πολλαπλά μπλοκ μνήμης σε χρόνο που αρχικοποιείται στο 0
  • Το Realloc () στο C χρησιμοποιείται για την ανακατανομή της μνήμης σύμφωνα με το καθορισμένο μέγεθος.
  • Η λειτουργία Free () χρησιμοποιείται για την εκκαθάριση της δυναμικά εκχωρημένης μνήμης.