Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Σχετικά έγγραφα
Προγραμματισμός Ι (ΗΥ120)

Προγραµµατισµός Ι 1

Διάλεξη 13η: Δυναμική Διαχείρηση Μνήμης, μέρος 1

Ανάπτυξη και Σχεδίαση Λογισμικού

Διάλεξη 9: Δυναμική Δέσμευση Μνήμης

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Η γλώσσα προγραμματισμού C Δυναμική διαχείριση μνήμης

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δυναμική Δέσμευση Μνήμης (Κεφάλαιο , KNK-2ED)

ιαφάνειες παρουσίασης #5 (β)

Η γλώσσα C. Δείκτες και Διαχείριση Μνήμης (memory management)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εισαγωγή στον Προγραμματισμό

Διαδικασιακός Προγραμματισμός

Προγραμματισμός Ι (ΗΥ120)

Προγραμμαηιζμός Ι ( ΗΥ120 )

Μνήμη Διευθύνσεις Δείκτες. Προγραμματισμός II 1

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Ι (ΗΥ120)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Προγραμματισμός Ι (ΗΥ120)

int a[5]; a[0] a[1] a[2] a[3] a[4] 15/10/2009

Εισαγωγή στον δομημένο προγραμματισμό

Βιβλιοθήκες Αφηρημένοι τύποι δεδομένων. Προγραμματισμός II 1

HY150a Φροντιστήριο 3 24/11/2017

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Δομημένος Προγραμματισμός (ΤΛ1006)

Σημειώσεις έκτης και έβδομης εβδομάδας

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

ΠΛΗ111. Ανοιξη Μάθηµα 1 ο Ανασκόπηση της Γλώσσας Προγραµµατισµού C. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Διάλεξη 10: Δομές Δεδομένων Ι (Στοίβες & Ουρές)

Προγραμματισμός Ι (ΗΥ120)

Διδάσκων: Παναγιώτης Ανδρέου

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Δομές Δεδομένων

ΠΡΟΗΓΜΕΝΟΙ ΜΙΚΡΟΕΠΕΞΕΡΓΑΣΤΕΣ PROJECT 2: MEMORY MANAGEMENT

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Δομές δεδομένων (2) Αλγόριθμοι

Διδάσκων: Παναγιώτης Ανδρέου

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Ι Αρχεία δεδομένων, μέρος δεύτερο: δυαδικά αρχεία ΙΙ Δομές δεδομένων (struct)

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Διάλεξη 18η: Διαχείρηση Αρχείων

Διδάσκων: Παναγιώτης Ανδρέου

Εισαγωγή στον Προγραμματισμό (με. τη C)

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Υπολογιστών με C++

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

ΗΥ-150. Προγραµµατισµός. υναµική ιαχείριση Μνήµης (1/2)

Φροντιστήριο 4 Σκελετοί Λύσεων

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Ενώσεις δεδομένων Απαριθμητές Ψηφιακοί τελεστές Αναδρομικές συναρτήσεις

ΚΑΤΑΣΚΕΥΑΣΤΕΣ ΑΝΤΙΓΡΑΦΗΣ

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Οι δείκτες στη γλώσσα C

Δομές Δεδομένων. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής. Δομές Δεδομένων. Τμήμα Εφαρμοσμένης Πληροφορικής

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΕΠΛ 035: οµές εδοµένων και Αλγόριθµοι για Ηλεκτρολόγους Μηχανικούς και Μηχανικούς Υπολογιστών

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δυναμική Δέσμευση Μνήμης και Δομές Δεδομένων (Φροντιστήριο)

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Γλώσσα Προγραμματισμού C

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Περιεχόμενα. Πρόλογος... 21

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Α' Περιόδου Θέµα 1. (α') 2 - ii 3 - iii 4 - iv

Δομημένος Προγραμματισμός (ΤΛ1006)

Διάλεξη 11η: Δείκτες, μέρος 1

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Η γλώσσα προγραμματισμού C

C: Από τη Θεωρία στην Εφαρμογή

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Επεξεργασία Αρχείων Κειµένου

ΗΥ-150. Προγραμματισμός

Σύνθετοι Τύποι εδοµένων. Προγραµµατισµός Ι 1

Προγραμματισμός Ι. Δομές Δεδομένων. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διάλεξη 20: Χαμηλού Επιπέδου Προγραμματισμός II

lab13grades Άσκηση 2 -Σωστά απελευθερώνετε ολόκληρη τη λίστα και την κεφαλή

Στοίβες με Δυναμική Δέσμευση Μνήμης

Δομημένος Προγραμματισμός (ΤΛ1006)

Ορισμός μεταβλητών δεικτών και αρχικοποίηση

Αλγόριθμοι Ταξινόμησης Μέρος 1

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

Ανάπτυξη και Σχεδίαση Λογισμικού

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Προγραμματισμός Ι. Εγγραφές. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός II. Δυναμική διαχείριση μνήμης

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Διδάσκων: Παναγιώτης Ανδρέου

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #5

Προεπεξεργαστής C. Προγραμματισμός Ι 1

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Διασυνδεδεμένες Δομές. Λίστες. Προγραμματισμός II 1

Φροντιστήριο 4 Σκελετοί Λύσεων

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Διάλεξη 5: Δείκτες και Συναρτήσεις

Transcript:

Δυναμική δέσμευση και αποδέσμευση μνήμης Προγραμματισμός II 1 lalis@inf.uth.gr

Γιατί χρειάζεται η δυναμική μνήμη; Οι απαιτήσεις του προγράμματος σε μνήμη μπορεί να είναι άγνωστες την ώρα της συγγραφής του κώδικα Αν για «ασφάλεια» χρησιμοποιήσουμε έναν τεράστιο αριθμό μεταβλητών ή τεράστιο στατικό πίνακα για να αποθηκεύσουμε τα δεδομένα, πιθανώς αυτή η μνήμη να μην χρησιμοποιηθεί ποτέ η μνήμη ουσιαστικά χάνεται καθώς δεν μπορεί να διατεθεί σε άλλα προγράμματα που εκτελούνται στον υπολογιστή Αν για «οικονομία» χρησιμοποιήσουμε ένα μικρότερο πίνακα, πιθανώς η μνήμη να μην φτάσει το πρόγραμμα είτε θα αναγκαστεί να πετάξει/χάσει κάποια δεδομένα είτε θα αναγκαστεί να τερματίσει Προγραμματισμός II 2 lalis@inf.uth.gr

Σχετικές συναρτήσεις / βιβλιοθήκες #include <stdlib.h> void *malloc(size_t size); void *calloc(size_t n, size_t size); void *realloc(void *p, size_t size); void free(void *p); #include <string.h> void *memcpy(void *dst, const void *src, size_t n); void *memset(void *p, int c, size_t n); int memcmp(const void *p1, const void *p2, size_t n); char *strdup(const char *s); Προγραμματισμός II 3 lalis@inf.uth.gr

Βασικές λειτουργίες void *malloc(size_t size); δεσμεύει ένα συνεχές κομμάτι μνήμης size bytes επιστρέφει έναν δείκτη στην αρχή του κομματιού τα περιεχόμενα της μνήμης δεν αρχικοποιούνται void free(void *ptr); αποδεσμεύει το κομμάτι μνήμης που δείχνει ο δείκτης ptr ο δείκτης πρέπει να έχει επιστραφεί από κάποια προηγούμενη λειτουργία δέσμευση μνήμης δεν επιτρέπεται/προβλέπεται να δοθεί ως παράμετρος μια οποιαδήποτε τυχαία διεύθυνση Προγραμματισμός II 4 lalis@inf.uth.gr

Βασικές λειτουργίες (2) void *calloc(size_t nmemb, size_t size); δεσμεύει ένα συνεχές κομμάτι μνήμης nmemb x size bytes επιστρέφει έναν δείκτη στην αρχή του κομματιού τα περιεχόμενα της μνήμης αρχικοποιούνται σε 0 void *realloc(void *ptr, size_t size); προσαρμόζει στα size bytes το κομμάτι μνήμης που δείχνει ο δείκτης ptr (το κομμάτι επεκτείνεται ή κόβεται, αναλόγως) τα προηγούμενα περιεχόμενα της μνήμης δεν αλλάζουν τυχόν επιπλέον bytes δεν αρχικοποιούνται πιθανή αντιγραφή των δεδομένων σε άλλη περιοχή της μνήμης, με απελευθέρωση του προηγούμενου κομματιού Προγραμματισμός II 5 lalis@inf.uth.gr

Χρήση δυναμικής μνήμης Η διεύθυνση που επιστρέφεται χρησιμοποιείται με αποκλειστική ευθύνη του προγραμματιστή οι λειτουργίες της δυναμικής μνήμης δεν γνωρίζουν τίποτα σχετικά με τους τύπους των δεδομένων του προγράμματος Συνήθως η μνήμη που δεσμεύεται αντιστοιχεί στο (πολλαπλάσιο) μέγεθος ενός αντικειμένου τύπου Τ Η διεύθυνση που επιστρέφεται, ανατίθεται (με type casting) σε μια μεταβλητή τύπου Τ* για την σωστή αποθήκευση/ερμηνεία των δεδομένων Ο προγραμματιστής πρέπει να αποδεσμεύει την δυναμική μνήμη που δεν χρησιμοποιεί το πρόγραμμα διαφορετικά υπάρχει περίπτωση η επόμενη αίτηση δέσμευσης να αποτύχει το πρόγραμμα να «ξεμείνει» από μνήμη Προγραμματισμός II 6 lalis@inf.uth.gr

Έλεγχος τιμής που επιστρέφεται Οι malloc και realloc επιστρέφουν NULL αν δεν μπορεί να δεσμευτεί όση μνήμη ζητήθηκε Η τιμή επιστροφής πρέπει να ελέγχεται Διαφορετικά, αν η τιμή NULL ανατεθεί σε δείκτη, η επόμενη αναφορά στη μνήμη μέσω του δείκτη θα οδηγήσει σε τερματισμό του προγράμματος μπορεί να μην επιθυμούμε ένα τέτοιο «απότομο» τερματισμό (και χάσιμο δεδομένων του προγράμματος) δεν γνωρίζουμε σε ποιο σημείο του προγράμματος έγινε αυτή η αναφορά (υπάρχει πάντα το debugging) Προγραμματισμός II 7 lalis@inf.uth.gr

#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int a,b,*sum; δέσμευση μνήμης από scanf("%d %d",&a,&b); sizeof(int) bytes sum = (int *) malloc( sizeof(int) ); if (sum == NULL) { printf("no memory\n"); return(1); type cast σε δείκτη-σε-ακέραιο *sum = a+b; printf("%d\n",*sum); free(sum); return(0); αποδέσμευση μνήμης Προγραμματισμός II 8 lalis@inf.uth.gr

Μονιμότητα δυναμικής μνήμης Η δυναμική μνήμη είναι μόνιμη, δηλαδή υφίσταται καθ όλη τη διάρκεια της εκτέλεσης του προγράμματος Δυναμική μνήμη που δεσμεύεται μέσα από μια συνάρτηση παραμένει εν ισχύ μετά την κλήση της Άλλος ένας τρόπος επιστροφής αποτελεσμάτων μέσα από το (προσωρινό) περιβάλλον κλήσης συνάρτησης η συνάρτηση δεσμεύει δυναμική μνήμη όπου αποθηκεύει τα δεδομένα, και επιστρέφει σαν αποτέλεσμα την διεύθυνση το περιβάλλον κλήσης χρησιμοποιεί τη διεύθυνση όπως απαιτείται ανάθεση σε κατάλληλη μεταβλητή δείκτη το περιβάλλον κλήσης πρέπει να αποδέσμευσει την μνήμη μετά την χρήση Προγραμματισμός II 9 lalis@inf.uth.gr

#include <stdio.h> #include <stdlib.h> int *add(int a, int b) { int *sum = (int *)malloc(sizeof(int)); *sum = a + b; return(sum); int main(int argc, char *argv[]) { int a, b, *sum; scanf("%d %d", &a, &b); sum = add(a, b); printf("%d\n", *sum); free(sum); return(0); Προγραμματισμός II 10 lalis@inf.uth.gr

#include <stdio.h> int *add(int a, int b) { γιατί είναι λάθος; int sum; sum = a + b; return(&sum); /* αυτό είναι λάθος! */ int main(int argc, char *argv[]) { int a, b, *sum; scanf("%d %d",&a, &b); sum = add(a, b); printf("%d\n", *sum); return(0); Προγραμματισμός II 11 lalis@inf.uth.gr

Δυναμικοί πίνακες Προγραμματισμός II 12 lalis@inf.uth.gr

Δυναμικοί πίνακες Κλασικό παράδειγμα χρήσης δυναμικής μνήμης 1. Δεσμεύεται με malloc ή realloc δυναμική μνήμη μεγέθους n*sizeof(t) όπου T ο τύπος δεδομένων των στοιχείων του πίνακα 2. Αν το n αποδειχθεί μικρό ή μεγάλο, χρησιμοποιείται η realloc για την επέκταση/κόψιμο του πίνακα. 3. Όταν ο πίνακας δεν χρειάζεται άλλο, η μνήμη που καταλαμβάνει μπορεί να αποδεσμευθεί με free Προγραμματισμός II 13 lalis@inf.uth.gr

το μέγεθος του πίνακα αλλάζει δυναμικά ως συνέπεια των λειτουργιών προσθήκης ή/και απομάκρυνσης δεδομένων απομάκρυνση προσθήκη μνήμη για τα στοιχεία του πίνακα Προγραμματισμός II 14 lalis@inf.uth.gr

little endian char *str = (char *) malloc(3*sizeof(char)); allocated memory 06 00?????? address x0000 address x000f Προγραμματισμός II 15 lalis@inf.uth.gr

little endian char *str = (char *) calloc(3,sizeof(char)); allocated memory 06 00 00 00 00 address x0000 address x000f Προγραμματισμός II 16 lalis@inf.uth.gr

little endian *str = (char *) realloc(str,5*sizeof(char)); allocated memory 06 00 00 00 00???? address x0000 additional memory address x000f Προγραμματισμός II 17 lalis@inf.uth.gr

little endian *str = (char *) realloc(str,2*sizeof(char)); allocated memory 06 00 00 00 address x0000 free superfluous memory address x000f Προγραμματισμός II 18 lalis@inf.uth.gr

little endian *str = (char *) realloc(str,4*sizeof(char)); free old memory allocate new memory 0C 00 00 00 00 00???? address x0000 copy old contents address x000f Προγραμματισμός II 19 lalis@inf.uth.gr

Παράδειγμα: τηλεφωνική ατζέντα Επιθυμούμε να διαχειριστούμε τα περιεχόμενα της τηλεφωνικής μας ατζέντας, με αντίστοιχες λειτουργίες προσθήκης, απομάκρυνσης και αναζήτησης Ορίζουμε κατάλληλη δομή για την ομαδοποίηση των δεδομένων που αποτελούν μια εγγραφή Διατηρούμε ένα δυναμικό πίνακα από τέτοιες δομές Οι λειτουργίες πρέπει να υλοποιηθούν σύμφωνα με κατάλληλες εσωτερικές συμβάσεις για την διαχείριση των στοιχείων του πίνακα Προγραμματισμός II 20 lalis@inf.uth.gr

phonebook *phonebook_create(); int phonebook_find(phonebook *b, const char name[], char phone[]); int phonebook_add(phonebook *b, const char name[], const char phone[]); void phonebook_rmv(phonebook *b, const char name[]); void phonebook_destroy(phonebook *b); Προγραμματισμός II 21 lalis@inf.uth.gr

typedef struct { char name[64]; char phone[64]; entry; typedef struct { entry* entries; /* dynamic table holding the entries */ int size; /* the current size of the table */ phonebook; Προγραμματισμός II 22 lalis@inf.uth.gr

phonebook *phonebook_create() { phonebook *b; b = (phonebook *) malloc(sizeof(phonebook)); b->size = 0; return(b); void phonebook_destroy(phonebook *b) { if (b->size>0) { free(b->entries); free(b); Προγραμματισμός II 23 lalis@inf.uth.gr

int find0(phonebook *b, const char name[]) { int i; for (i=0; (i < b->size) && (strcmp(b->entries[i].name,name)); i++); return(i); int phonebook_find(phonebook *b, const char name[], char phone[]) { int pos; pos = find0(b,name); if (pos == b->size) return(0); /* not found */ else { strcpy(phone,b->entries[pos].phone); return(1); /* found */ Προγραμματισμός II 24 lalis@inf.uth.gr

int phonebook_add(phonebook *b, const char name[], const char phone[]) { int pos; pos = find0(b,name); if (pos < b->size) { strcpy(b->entries[pos].phone,phone); return(-1); /* replaced */ επέκταση b->size++; b->entries = (entry *) realloc(b->entries,b->size*sizeof(entry)); strcpy(b->entries[b->size-1].name,name); strcpy(b->entries[size-1].phone,phone); return(1); /* added */ Προγραμματισμός II 25 lalis@inf.uth.gr

void phonebook_rmv(phonebook *b, const char name[]) { int pos; pos = find0(name); if (pos < b->size) { memcopy(&b->entries[pos], &b->entries[b->size-1],sizeof(entry)); b->size--; b->entries = (entry *) realloc(b->entries,b->size*sizeof(entry)); κόψιμο Προγραμματισμός II 26 lalis@inf.uth.gr

Παρατήρηση Κάθε φορά που απομακρύνεται ένα στοιχείο, γίνεται μια αντιγραφή δεδομένων από την τελευταία θέση, στην θέση που ελευθερώθηκε Αυτό μπορεί να είναι ιδιαίτερα χρονοβόρο αν τα περιεχόμενα της δομής είναι μεγάλα σε μέγεθος Μπορούμε να αποφύγουμε αυτή την αντιγραφή, χρησιμοποιώντας ένα πίνακα από δείκτες σε (αυτόνομα) αντικείμενα δεδομένων η μνήμη των οποίων δεσμεύεται και αποδεσμεύεται δυναμικά κατά την προσθήκη / απομάκρυνση τους Οι «αντιμεταθέσεις» στοιχείων γίνονται γρήγορα, ανεξάρτητα από το μέγεθος των αντικειμένων Προγραμματισμός II 27 lalis@inf.uth.gr

memory for the table of pointers to data records memory for individual data record Προγραμματισμός II 28 lalis@inf.uth.gr