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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

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

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

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

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

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

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

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

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

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

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

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

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

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

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

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

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

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

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

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

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

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

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

Εισαγωγή στη γλώσσα προγραμματισμού C++

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

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

3.1 Αριθμητικοί και Λογικοί Τελεστές, Μετατροπές Τύπου (Casting)

Δομημένος Προγραμματισμός

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

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

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

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

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

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

Προγραμματισμός Ι. Δομές & Ενώσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Διάλεξη 6: Δείκτες και Πίνακες

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

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

Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών

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

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

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

Αντικειμενοστρεφής Προγραμματισμός Διάλεξη 2 : ΜΕΤΑΒΛΗΤΕΣ ΤΕΛΕΣΤΕΣ & ΕΚΦΡΑΣΕΙΣ ΕΛΕΓΧΟΣ ΡΟΗΣ

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

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

Προγραμματισμός Η/Υ. Ενότητα 2β: Εισαγωγή στη C (Μέρος Δεύτερο)

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

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

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

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

Μεθόδων Επίλυσης Προβλημάτων

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

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

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

Κεφάλαιο 2.5: Τύποι εδοµένων, Τελεστές και Αριθµητικές Εκφράσεις. ( ιαλέξεις 5-6) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

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

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

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

ΕΡΓΑΣΤΗΡΙΟ 8: Πολυδιάστατοι Πίνακες και Δυναμική Δέσμευση Μνήμης

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

Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 131 Αρχές Προγραµµατισµού I 3-2

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

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

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

H ΓΛΩΣΣΑ C. Μάθηµα 12: υναµική έσµευση Μνήµης. ηµήτρης Ψούνης

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

scanf() scanf() stdin scanf() printf() int float double %lf float

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

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

1 ΕΙΣΑΓΩΓΗ. Πρωταρχικοί Τύποι

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

Κεφάλαιο 2.5: Τύποι Δεδομένων, Τελεστές και Αριθμητικές Εκφράσεις. (Διαλέξεις 5-6)

5 &6. Τύποι δεδομένων, τελεστές και

Μεθόδων Επίλυσης Προβλημάτων

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Η γλώσσα προγραμματισμού C Οι συναρτήσεις στη C (2)

Transcript:

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

Ανάγκη για Δυναμική Μνήμη Στατική Μνήμη Μέχρι τώρα χρησιμοποιούσαμε στατική μνήμη, δηλαδή τα προγράμματα μας ήξεραν από πριν (την ώρα την μεταγλώττισης) πόση μνήμη χρειάζεται. Τι γίνεται όμως όταν δεν ξέρουμε πόση ακριβώς μνήμη χρειαζόμαστε; π.χ Θέλουμε να γράψουμε ένα πρόγραμμα που να διαβάζει ένα σύνολο ακεραίων από ένα αρχείο και να τους ταξινομεί σε μη-φθίνουσα σειρά. Πόσους όμως ακέραιους; Χαροκόπειο Πανεπιστήμιο 2/31

Stack και Heap Η μνήμη που καταλαμβάνει ένα πρόγραμμα διαχωρίζεται σε διάφορα μέρη. Ένα κομμάτι όπου φορτώνεται ο κώδικας του προγράμματος μας Ένα κομμάτι όπου βρίσκονται οι στατικές μεταβλητές Την στοίβα (stack) όπου αποθηκεύονται όλες οι τοπικές μεταβλητές, οι παράμετροι των συναρτήσεων, προσωρινές μεταβλητές, κ.τ.λ. Τον σωρό (heap) όπου είναι μνήμη που μπορούμε να την δεσμεύσουμε ή να την ελευθερώσουμε κατά την διάρκεια του προγράμματος. code static data stack heap Χαροκόπειο Πανεπιστήμιο 3/31

Διαχείριση Μνήμης Λειτουργικό Σύστημα Την διαχείριση μνήμης την αναλαμβάνει το λειτουργικό σύστημα. Η C μας παρέχει στην βιβλιοθήκη της, διάφορες συναρτήσεις που είναι υπεύθυνες ώστε να μας παραχωρήσει το λειτουργικό σύστημα μνήμη. Η μέγιστη μνήμη που το πρόγραμμα μας μπορεί να ζητήσει έχει να κάνει με: την συνολική μνήμη του συστήματος, πόση μνήμη είναι διαθέσιμη για προγράμματα χρηστών, πόσα άλλα προγράμματα τρέχουν ταυτόχρονα και πόση μνήμη έχουν δεσμεύσει. Χαροκόπειο Πανεπιστήμιο 4/31

Ο Τελεστής sizeof() Για να ζητήσουμε μνήμη από το σύστημα πρέπει να ξέρουμε πόση μνήμη χρειαζόμαστε. Η C μας παρέχει τον τελεστή sizeof() ώστε να μπορούμε να μάθουμε πόση μνήμη σε bytes καταναλώνουν οι διάφοροι τύποι στην C. Χαροκόπειο Πανεπιστήμιο 5/31

Ο Τελεστής sizeof() Παραδείγματα 1 #include <stdio. h> 2 3 int main ( ) 4 { 5 printf ( "size of char in bytes = %lu\n", sizeof (char ) ) ; 6 printf ( "size of int in bytes = %lu\n", sizeof (int ) ) ; 7 printf ( "size of long in bytes = %lu\n", sizeof (long ) ) ; 8 printf ( "size of double in bytes = %lu\n", sizeof (double ) ) ; 9 printf ( "size of void* in bytes = %lu\n", sizeof (void * ) ) ; 10 11 return 0; 12 } με έξοδο (στο σύστημα του ομιλητή) size of char in bytes = 1 size of int in bytes = 4 size of long in bytes = 8 size of double in bytes = 8 size of void* in bytes = 8 Χαροκόπειο Πανεπιστήμιο 6/31

Ο Τελεστής sizeof() Παραδείγματα 1 #include <stdio. h> 2 3 typedef struct { 4 long AM ; 5 char name [ 5 6 ] ; 6 } student ; 7 8 int main ( ) 9 { 10 printf ( "size of student in bytes = %lu\n", sizeof (student ) ) ; 11 return 0; 12 } με έξοδο (στο σύστημα του ομιλητή) size of student in bytes = 64 Χαροκόπειο Πανεπιστήμιο 7/31

Ο Τελεστής sizeof() Παραδείγματα Προσοχή με το μέγεθος ενός struct γιατί πολλές φορές ο μεταγλωττιστής προσθέτει επιπλέον bytes στο τέλος ώστε να βελτιστοποιήσει την αντιγραφή (οι λεπτομέρειες εξαρτώνται από την CPU, το λειτουργικό και τον μεταγλωττιστή). 1 #include <stdio. h> 2 3 typedef struct { 4 long AM ; 5 char name [ 5 0 ] ; 6 } student ; 7 8 int main ( ) 9 { 10 printf ( "size of student in bytes = %lu\n", sizeof (student ) ) ; 11 12 return 0; 13 } το παραπάνω πρόγραμμα ενώ θα έπρεπε να τυπώνει 58, στο σύστημα του ομιλητή τυπώνει size of student in bytes = 64 Χαροκόπειο Πανεπιστήμιο 8/31

Ο Τελεστής sizeof() Ως τώρα δώσαμε στον τελεστή sizeof() τύπους δεδομένων. Μπορούμε όμως να δώσουμε και μεταβλητές. 1 #include <stdio. h> 2 3 int main ( ) 4 { 5 double x ; 6 double a [ 3 0 ] ; 7 8 printf ( "size of x in bytes = %lu\n", sizeof (x ) ) ; 9 printf ( "size of a in bytes = %lu\n", sizeof (a ) ) ; 10 11 return 0; 12 } size of x in bytes = 8 size of a in bytes = 240 Χαροκόπειο Πανεπιστήμιο 9/31

Ο Τελεστής sizeof() Προσοχή με τους δείκτες και τους πίνακες. 1 #include <stdio. h> 2 3 int main ( ) 4 { 5 double a [ 3 0 ] ; 6 double *p = a ; 7 8 printf ( "size of a in bytes = %lu\n", sizeof (a ) ) ; 9 printf ( "size of p in bytes = %lu\n", sizeof (p ) ) ; 10 11 return 0; 12 } size of a in bytes = 240 size of p in bytes = 8 Χαροκόπειο Πανεπιστήμιο 10/31

Ο Τελεστής sizeof() Προσοχή με τους δείκτες και τους πίνακες. 1 #include <stdio. h> 2 3 void printarray (double a [ 3 0 ] ) { 4 / /... 5 6 printf ( "size of a in bytes = %lu\n", sizeof (a ) ) ; 7 } 8 9 int main ( ) 10 { 11 double a [ 3 0 ] ; 12 13 printf ( "size of a in bytes = %lu\n", sizeof (a ) ) ; 14 printarray (a ) ; 15 16 return 0; 17 } size of a in bytes = 240 size of a in bytes = 8 Θυμηθείτε πως σε μία συνάρτηση περνάμε μόνο την διεύθυνση ενός πίνακα ως παράμετρο. Χαροκόπειο Πανεπιστήμιο 11/31

Προτεραιότητα Τελεστών.1 παρενθέσεις: () []. > expr++ expr Υπολογίζονται πρώτα, από τα αριστερά προς τα δεξιά. Εάν υπάρχουν ένθετες υπολογίζονται πρώτα οι εσωτερικές..2 μοναδιαίοι τελεστές: + ++expr expr! * & sizeof Υπολογίζονται από δεξιά προς τα αριστερά..3 πολλαπλασιασμός, διαίρεση και υπόλοιπο: * / % Υπολογίζονται δεύτερα από αριστερά προς τα δεξιά..4 πρόσθεση, αφαίρεση: + Εάν υπάρχουν πολλοί, υπολογίζονται από τα αριστερά προς τα δεξιά..5 Σχεσιακοί: < > <= >= Υπολογίζονται από τα αριστερά προς τα δεξιά..6 Ισότητας: ==!= Υπολογίζονται από τα αριστερά προς τα δεξιά..7 λογικό AND: && Από αριστερά προς τα δεξιά..8 λογικό OR: Από αριστερά προς τα δεξιά..9 εκχώρησης: = += = *= /= %= Από δεξιά προς τα αριστερά. Χαροκόπειο Πανεπιστήμιο 12/31

Η συνάρτηση malloc() Η συνάρτηση malloc είναι ορισμένη στο αρχείο stdlib.h και είναι υπεύθυνη για την δημιουργία μνήμης στον σωρό (heap). void* malloc(size_t size) πέρνει ως είσοδο το μέγεθος μνήμης που θέλουμε να δεσμεύσουμε σε bytes, σε περίπτωση επιτυχίας επιστρέφει έναν δείκτη στη διεύθυνση μνήμης που δεσμεύτηκε, εαν η μνήμη δεν δεσμεύτηκε (π.χ δεν υπάρχει άλλη ελεύθερη μνήμη στο σύστημα) επιστρέφει NULL. Χαροκόπειο Πανεπιστήμιο 13/31

Δείκτης σε Τύπο void Μετατροπή (casting) Η συνάρτηση malloc επιστρέφει ένα δείκτη σε τύπο void. Ο προγραμματιστής πρέπει στην συνέχεια να μετατρέψει στον τύπο που χρειάζεται (casting). 1 #include < s t d i o. h> 2 #include < s t d l i b. h> 3 4 int main ( ) 5 { 6 int *x = ( int * ) malloc ( sizeof ( int ) ) ; 7 8 / /... 9 10 return 0; 11 } Ο παραπάνω κώδικας φτιάχνει έναν ακέραιο. Χαροκόπειο Πανεπιστήμιο 14/31

Type Casting Η μετατροπή μιας έκφρασης ενός τύπου σε έναν άλλο..1 έμμεση μετατροπή Γίνονται αυτόματα όταν μια τιμή αντιγράφεται σε έναν συμβατό τύπο. short a = 2000; int b = a ; Επιτρέπεται μόνο αν δεν χάνεται πληροφορία..2 άμεση μετατροπή Υποδείχνουμε εμείς την μετατροπή. float a = 5. 2 5 ; int b = ( int ) a ; Προσοχή με την χρήση των typecasts, πολλές φορές οδηγούν σε πολύ δυσεύρετα λάθη. Χαροκόπειο Πανεπιστήμιο 15/31

Προτεραιότητα Τελεστών.1 παρενθέσεις: () []. > expr++ expr Υπολογίζονται πρώτα, από τα αριστερά προς τα δεξιά. Εάν υπάρχουν ένθετες υπολογίζονται πρώτα οι εσωτερικές..2 μοναδιαίοι τελεστές: + ++expr expr! * & sizeof (typecast) Υπολογίζονται από δεξιά προς τα αριστερά..3 πολλαπλασιασμός, διαίρεση και υπόλοιπο: * / % Υπολογίζονται δεύτερα από αριστερά προς τα δεξιά..4 πρόσθεση, αφαίρεση: + Εάν υπάρχουν πολλοί, υπολογίζονται από τα αριστερά προς τα δεξιά..5 Σχεσιακοί: < > <= >= Υπολογίζονται από τα αριστερά προς τα δεξιά..6 Ισότητας: ==!= Υπολογίζονται από τα αριστερά προς τα δεξιά..7 λογικό AND: && Από αριστερά προς τα δεξιά..8 λογικό OR: Από αριστερά προς τα δεξιά..9 εκχώρησης: = += = *= /= %= Από δεξιά προς τα αριστερά. Χαροκόπειο Πανεπιστήμιο 16/31

Η συνάρτηση free() Ο προγραμματιστής είναι υπεύθυνος να ελευθερώσει την μνήμη που δέσμευσε με την χρήση της συνάρτησης: void free ( void* ptr ) ; Η συνάρτηση ελευθερώνει την μνήμη που δείχνει ο δείκτης ptr και έχει δεσμευτεί με την malloc(). Για κάθε κλήση της malloc() πρέπει να υπάρχει και μία κλήση της free(). Χαροκόπειο Πανεπιστήμιο 17/31

Παράδειγμα Χρήσης της malloc() Δημιουργία struct 1 #include <stdio. h> 2 #include < s t d l i b. h> 3 4 typedef struct { 5 int AM ; 6 char name [ 5 0 ] ; 7 } student ; 8 9 int main ( ) 10 { 11 student *x = (student * ) malloc (sizeof (student ) ) ; 12 13 / / use x 14 15 free ( x ) ; 16 return 0; 17 } Χαροκόπειο Πανεπιστήμιο 18/31

Δημιουργία Πίνακα Η δημιουργία δυναμικού πίνακα γίνεται ζητώντας από την malloc() ένα πολλαπλάσιο σε bytes του τύπου που θέλουμε. 1 #include <stdio. h> 2 #include < s t d l i b. h> 3 4 int main ( ) 5 { 6 int n = 100, i, *array ; 7 8 array = (int * ) malloc (n * sizeof (int ) ) ; 9 10 for ( i = 0; i < n ; i++) 11 array [ i ] = i*i ; 12 for ( i = 0; i < n ; i++) 13 printf ( "%d ", array [ i ] ) ; 14 15 free (array ) ; 16 17 return 0; 18 } Προσοχή η μνήμη που επιστρέφει η malloc() δεν έχει αρχικοποιηθεί. Χαροκόπειο Πανεπιστήμιο 19/31

Παράδειγμα Χρήσης της malloc() Δημιουργία Πίνακα 1 #include <stdio. h> 2 #include < s t d l i b. h> 3 4 typedef struct { 5 int AM ; 6 char name [ 5 0 ] ; 7 } student ; 8 9 int main ( ) 10 { 11 int n = 100, i ; 12 student *array = (student * ) malloc (n * sizeof (student ) ) ; 13 14 / / use array 15 16 free (array ) ; 17 return 0; 18 } Χαροκόπειο Πανεπιστήμιο 20/31

Διαρροή Μνήμης Memory Leaks Διαρροή μνήμης έχουμε εαν ξεχάσουμε να ελευθερώσουμε την μνήμη που δεσμεύσαμε. Η μνήμη αυτή παραμένει άχρηστη μέχρι το λειτουργικό σύστημα να την ελευθερώσει. Είναι συνήθης λόγος προβλημάτων προγραμματισμού. Ένα πρόγραμμα με διαρροή μνήμης δημιοργεί προβλήματα στο σύστημα και έχει μεγάλες πιθανότητες να τερματιστεί πρόωρα. Χαροκόπειο Πανεπιστήμιο 21/31

Πίνακας με Δείκτες Δείκτες σε Δείκτες Για να φτιάξουμε δυναμικά έναν πίνακα με δείκτες χρειαζόμαστε ένα δείκτη που να δείχνει σε τύπο δείκτη. Όταν γράφουμε int *p ; δηλώνουμε ένα δείκτη με όνομα p που δείχνει σε τύπο ακέραιο. Αντίστοιχα γράφουμε int * * p ; για δηλώνουμε ένα δείκτη με όνομα p που να δείχνει σε τύπο δείκτη σε ακέραιο. Θα μπορούσαμε να το γράφαμε ως int* *p για να είναι πιο σαφές. Χαροκόπειο Πανεπιστήμιο 22/31

Πίνακας με Δείκτες Δείκτες σε Δείκτες Για να φτιάξουμε δυναμικά έναν πίνακα με δείκτες χρειαζόμαστε ένα δείκτη που να δείχνει σε τύπο δείκτη. int * * ptrarray = (int * * ) malloc(100 * sizeof (int * ) ) ; Ζητάμε από την malloc() να μας επιστρέψει ένα πίνακα με μέγεθος 100 επί το μέγεθος που καταναλώνει ένας δείκτης σε ακέραιο. Κάθε στοιχείο π.χ ptrarray[4] είναι ένας δείκτης σε ακέραιο. Χαροκόπειο Πανεπιστήμιο 23/31

Πίνακας με Δείκτες Δείκτες σε Δείκτες Για να φτιάξουμε δυναμικά έναν πίνακα με δείκτες χρειαζόμαστε ένα δείκτη που να δείχνει σε τύπο δείκτη. int * * ptrarray = (int * * ) malloc(100 * sizeof (int * ) ) ; ptrarray Χαροκόπειο Πανεπιστήμιο 23/31

Διδιάστατος Δυναμικός Πίνακας Για να φτιάξουμε ένα δυναμικό διδιάστατο πίνακα φτιάχνουμε πρώτα ένα πίνακα με δείκτες. Αυτός ο πίνακας αντιστοιχεί στις γραμμές του διδιάστατου πίνακα. a int * * a = ( int * * ) malloc(100 * sizeof ( int * ) ) ; Στην συνέχεια φτιάχνουμε ένα πίνακα για κάθε γραμμή. for ( i = 0; i < 100; i++) a [ i ] = (int * ) malloc(50 * sizeof (int ) ) ; a[i] Χαροκόπειο Πανεπιστήμιο 24/31

Διδιάστατος Δυναμικός Πίνακας a Γράφοντας a[i] μας επιστρέφεται ένας δείκτης. Γράφοντας a[i][j] μας επιστρέφεται ο ακέραιος που αντιστοιχεί στην θέση i, j του πίνακα. a[i] a[i][j] Γιατί; Θυμηθείτε πως ο μεταγλωττιστής μετατρέπει το a[i] σε *(a+i). Η έκφραση a[i][j] μετατρέπεται σε *(*( a+i)+j). Χαροκόπειο Πανεπιστήμιο 25/31

Διδιάστατος Δυναμικός Πίνακας Δημιουργία και καταστροφή διδιάστατου πίνακα. #include < s t d l i b. h> main ( ) { int i, * * a ; a = ( int * * ) malloc(100 * sizeof ( int * ) ) ; for ( i = 0; i < 100; i++) a [ i ] = (int * ) malloc(50 * sizeof (int ) ) ; / / here we can use the 100x50 array / / a [ i ] [ j ] i s element at row i and column j for ( i = 0; i < 100; i++) free ( a [ i ] ) ; free ( a ) ; } return 0; Ελευθερώνουμε την μνήμη με την αντίστροφη σειρά. Χαροκόπειο Πανεπιστήμιο 26/31

Συχνά Λάθη Έλεγχος Τιμής Επιστροφής malloc() Η malloc() επιστρέφει είτε την μνήμη που δεσμεύτηκε είτε NULL σε περίπτωση που έγινε λάθος. Πρέπει πάντα να ελέγχουμε την τιμή επιστροφής Σε περίπτωση που το λειτουργικό δεν έχει διαθέσιμη μνήμη η malloc() θα επιστρέψει NULL. Εάν δεν κάνουμε έλεγχο, μόλις προσπελάσουμε αυτόν τον δείκτη το πρόγραμμα μας θα τερματιστεί βίαια. Χαροκόπειο Πανεπιστήμιο 27/31

Συχνά Λάθη Έλεγχος Τιμής Επιστροφής malloc() #include <stdio. h> #include < s t d l i b. h> int main ( ) { int *x = (int * ) malloc(100 * sizeof (int ) ) ; x [ 3 ] = 15; free ( x ) ; return 0; } Εάν η malloc() επιστρέψει NULL τότε θα εκτελεστεί ο παρακάτω κώδικας που προκαλεί βίαιο τερματισμό. #include <stdio. h> #include < s t d l i b. h> int main ( ) { int *x = 0; x [ 3 ] = 15; free ( x ) ; return 0; } / / ERROR! Χαροκόπειο Πανεπιστήμιο 28/31

Συχνά Λάθη Έλεγχος Τιμής Επιστροφής malloc() Ο σωστός τρόπος χρήσης της συνάρτησης malloc() είναι λοιπόν: #include <stdio. h> #include < s t d l i b. h> int main ( ) { int *x = (int * ) malloc(100 * sizeof (int ) ) ; if ( x == NULL ) { fprintf (stderr, "Could not allocate memory!" ) ; abort ( ) ; } } x [ 3 ] = 15; free ( x ) ; return 0; Χαροκόπειο Πανεπιστήμιο 29/31

Συχνά Λάθη Πολλαπλή Κλήση της free() Η κλήση της συνάρτησης free( ptr ) ελευθερώνει την μνήμη που δείχνει ο δείκτης ptr. Αυτή η μνήμη πρέπει να έχει πρωτύτερα δεσμευτεί με την χρήση της malloc(). Σε περίπτωση που η μνήμη που δείχνει ο ptr έχει ήδη ελευθερωθεί από μια προηγούμενη κλήση της free() η συμπεριφορά του προγράμματος είναι απρόβλεπτη. Χαροκόπειο Πανεπιστήμιο 30/31

Συχνά Λάθη Πολλαπλή Κλήση της free() Σε περίπτωση που η μνήμη που δείχνει ο ptr έχει ήδη ελευθερωθεί από μια προηγούμενη κλήση της free() η συμπεριφορά του προγράμματος είναι απρόβλεπτη. #include <stdio. h> #include < s t d l i b. h> int main ( ) { int *x = (int * ) malloc(100 * sizeof (int ) ) ; if (! x ) { fprintf (stderr, "Cannot allocate memory!" ) ; abort ( ) ; } } free ( x ) ; free (x ) ; / / ERROR! undefined behavior return 0; Χαροκόπειο Πανεπιστήμιο 31/31