Σας ευχαριστώ πολύ χαρης την βοήθειά σας μπορώ να φτιάχνω πολά προγράμματα στην c με σχέσει την δυναμική δέσμευση μνήμης και συνδιαζω παράλληλα και άλλες τεχνικές που μας έχετε μάθει. Καλή πρόοδο
6:23 Δλδ για να καταλαβω: εχω 2 πινακες. Εναν τυπου ο.τι θελω, με ΜχN γραμμες και στηλες. Κι εναν αλλο τυπου ο.τι κι ο πρωτος, με Μ γραμμες και 1 στηλη. Αυτος ειναι πινακας δεικτων και δειχνει για καθε γραμμη, στο πρωτο κελι του αλλου πινακα. Ετσι εχουμε προσβαση στον μεγαλο πινακα, απο τον πινακα δεικτων. Σωστο ή λαθος?
+eimaisklhros Έχω 1 πίνακα (διδιαστατο). Δεν τον δηλώνω με τον κλασικό τρόπο (στατικά όπως είδαμε στο μάθημα 5). Τον δηλώνω με καινούριο τρόπο. Δυναμικά δηλώνοντας Μ+1 πίνακες. Πιστεύω θα βοηθήσουν οι ασκήσεις. Αλλος τρόπος δέσμευσης της μνήμης. Ίδια συμπεριφορά στον πίνακα.
Χοντρικά, υπάρχουν δύο διαχειρίσης της μνήμης: - Κάθε συνάρτηση, όπως η main, έχει το δικό της χώρο στη μνήμη. Οι μεταβλητές και οι πίνακες που δηλώνουμε στατικά, δεσμεύουν χώρο εκεί. Όταν τελειώσει η εκτέλεση της συνάρτησης ο χώρος αυτός απελευθερώνεται για όλη τη συνάρτηση, συνολικά, άρα απελευθερώνεται για όλες τις μεταβλητές και τους πίνακες που έχουμε δηλώσει. Δεν χρειάζεται να κάνουμε κάποια ενέργεια. - Με τη malloc γίνεται άλλη διαχείριση. Υπάρχει ένας ξεχωριστός χώρος συνολικά στο πρόγραμμα (αναφέρεται ως "heap") και όταν κάνουμε malloc δεσμεύεται χώρος από αυτόν (και όχι από το χώρο της συνάρτησης) και διατηρείται δεσμευμένος ανεξάρτητα από τις συναρτήσεις που δημιουργούνται και ολοκληρώνονται. Συνεπώς είναι προγραμματιστική μας ευθύνη να κάνουμε σωστή διαχείριση του heap και να απελευθερώνουμε το χώρο, όταν δεν τον χρειαζόμαστε πια.
Καλησπέρα, στην αρχή του βίντεο οι διευθύνσεις pin[0] ,pin[1], pin[2] κλπ δεν θα έπρεπε να έχουν διάφορα μεταξύ τους 4 θέσεις στην μνήμη αφού τις δηλώνουμε ως Int;Το Pin[0][0] από το pin[0][1] κλπ μου το βγάζει κανονικά ανά 4 θέσεις ενώ το pin[0] ,pin[1], pin[2] ανά 8 θέσεις.
Γενικά όταν δεν μπορεί να δεσμευτεί το μπλοκ που ζητάμε. Σε δύο περιπτώσεις: α/ π.χ. ζητάμε κάτι πολύ μεγάλο, ας πούμε 10.000.000.000 bytes (10 gb) και ο υπολογιστής δεν έχει τόση μνήμη β/ Η μνήμη έχει δεσμευτεί από άλλα προγράμματα και το λειτουργικό στο οποίο διοχετεύουμε το αίτημα, το αρνείται μιας και δεν μπορεί να βρει τέτοιο μπλοκ μνήμης ελεύθερο.
Καλησπέρα δάσκαλε, έχω παρατηρήσει (εάν εφαρμόζω σωστά αυτά που λέτε) ότι η malloc προσπαθεί να "βάλει" τους μονοδιάστατους πίνακες σε σειρά στην μνήμη χωρίς αυτό να είναι αναγκαίο πάντα. Όταν αυτό συμβαίνει βλέπω ότι ανάμεσα στις "γραμμές" ανάλογα τον IDE που χρησιμοποιώ (VS code / Dev C++) υπάρχει ένα "κενό" συνήθως 12 bytes στον 1ον και 28 στον 2ο αντίσοιχα. Έψαξα στο stackoverflow και νομίζω βρήκα παρόμοιο post stackoverflow.com/questions/15300901/c-programming-2d-array-malloc-interesting-values-after-every-row-seek-explana. Σε περίπτωση που βγάζουν νόημα τα παραπάνω θέλω να ρωτήσω 2 πράγματα: 1ον) Στην περίπτωση που η μια γραμμή είναι σε εντελώς "άσχετη" θέση με τις υπόλοιπες, δεν αποτελεί κάποιον κίνδυνο αυτό για την λειτουργία του προγράμματος ή για την οργάνωση των δεδομένων μας στη μνήμη; 2ον) Πρέπει να γνωρίζουμε για αυτά τα bytes ανάμεσα στις γραμμές ή είναι κάτι το οποίο δεν μπορεί να επηρεάσει το πρόγραμμά μας;
Πολύ ωραία, εμπλούτισες και τις γνώσεις μου ;-) Αυτές τις λεπτομέρειες που έχει το εκτενές άρθρο δεν τις είχα υπόψη... Αυτό που πρέπει να πω είναι ότι γνωρίζοντας ότι κάθε malloc δεσμεύει κάποιο χώρο χωρίς να προσδιορίζουμε εμείς ακριβώς ποιος θα είναι, αλλά πόσα bytes θα είναι και με βάση το γεγονός ότι εδώ κάνουμε Ν+1 διαφορετικά malloc, έπεται ότι μπορούν να είναι οπουδήποτε στη μνήμη και όχι σε διαδοχικές θέσεις. Γιατί όμως να είναι πρόβλημα αυτό; Αφού όταν γράφουμε π.χ. array[i][j] πάει πρώτα στο array και βρίσκει τον πίνακα δεικτών, έπειτα στο array[i] για να βρει τη γραμμή και έπειτα στο array[i][j] που είναι πλέον το συγκεκριμένο στοιχείο. Συνεπώς με τη συνηθισμένη χρήση που κάνουμε, αυτές οι λεπτομέρειες δεν μας αφορούν στην πράξη, αλλά απλά γίνονται στο παρασκήνιο. Τέλος, για τη 2η ερώτηση, δεν βλέπω κανέναν καλό λόγο, ιδίως στο επίπεδο που είμαστε, να γνωρίζουμε κάτι γι' αυτά. Αν γίνουμε δορυφορικοί world-experts στη C τότε ναι (αλλά πιστεύω μόνο σε τέτοιο επίπεδο) θα ήταν χρήσιμο κάτι σαν κι αυτό..
Κάποιο θέμα θα έχει ο μεταγλωττιστής που χρησιμοποιείς, προσπάθησε το με ρητό casting: /* Dynamiki Desmeysi mnimis */ p=(int **)malloc(sizeof(int*)*M); if (!p) { printf("Adynamia desmeusis mnimis"); exit(0); } for (i=0; i
το τμημα του κωδικα που ελεγχει την δεσμευση μνημνης και εκτυπωνει την τυχουσα αδυναμια δεσμευση μνημης θα μπορουσε να ειναι μια συναρτηση που να καλειται και να μην γραφουμε το if(!p)... καθε φορα΄;
@@kavourakos otan kaneis malloc tha prepei na to grapsis etsi (giati einai allh ekdosh metaglotisth ) int **arr = (int **)malloc(M * sizeof(int *)); (gia na diloseis oti thes enan pointer na desmeusei xwro gia alloys pointer ) enw otan thes gia kathe pointer na desmeusei xwro gia akaireous kanei se ena loop arr[i]=(int*)malloc(N*sizeof(int)); afou to arr[i] einai sthn ousia enas dikths !!! elpizw na boithisa
Σας ευχαριστώ πολύ χαρης την βοήθειά σας μπορώ να φτιάχνω πολά προγράμματα στην c με σχέσει την δυναμική δέσμευση μνήμης και συνδιαζω παράλληλα και άλλες τεχνικές που μας έχετε μάθει. Καλή πρόοδο
Επίσης είμαι 11 χρονών και ασχολουμε με την Πληροφορική από τα 8 μου και περιμένω κάθε μέρα πως και πως καινούριο βίντεό σας
Μπράβο φίλε, είσαι ο νεότερος που έχει δει μαθήματά μου. Να είσαι πάντα καλά και κάθε μέρα να μαθαίνεις και κάτι καινούργιο! Μπράβο και πάλι μπράβο!
το μάθημα απαιτεί νταφού
Αμα θελουμε πίνακα δισδιάστατο με χαρακτήρα σε κάθε κελί τι αλλάζει; Απλά βάζουμε char?
6:23 Δλδ για να καταλαβω:
εχω 2 πινακες. Εναν τυπου ο.τι θελω, με ΜχN γραμμες και στηλες.
Κι εναν αλλο τυπου ο.τι κι ο πρωτος, με Μ γραμμες και 1 στηλη. Αυτος ειναι πινακας δεικτων και δειχνει για καθε γραμμη, στο πρωτο κελι του αλλου πινακα. Ετσι εχουμε προσβαση στον μεγαλο πινακα, απο τον πινακα δεικτων. Σωστο ή λαθος?
+eimaisklhros Έχω 1 πίνακα (διδιαστατο). Δεν τον δηλώνω με τον κλασικό τρόπο (στατικά όπως είδαμε στο μάθημα 5). Τον δηλώνω με καινούριο τρόπο. Δυναμικά δηλώνοντας Μ+1 πίνακες. Πιστεύω θα βοηθήσουν οι ασκήσεις. Αλλος τρόπος δέσμευσης της μνήμης. Ίδια συμπεριφορά στον πίνακα.
@@psounis που μπορώ να βρώ τις ασκήσεις και τον κώδικα του video;
@@thodorisnikolovgenis7723 sto github,kane search ta mathimata stin c kai tha deis oti yparxoun taksinomimena
Γιατί η δυναμική δέσμευεση μνήμης χρειάζεται μετά την free ενώ η στατική όχι;
Χοντρικά, υπάρχουν δύο διαχειρίσης της μνήμης:
- Κάθε συνάρτηση, όπως η main, έχει το δικό της χώρο στη μνήμη. Οι μεταβλητές και οι πίνακες που δηλώνουμε στατικά, δεσμεύουν χώρο εκεί. Όταν τελειώσει η εκτέλεση της συνάρτησης ο χώρος αυτός απελευθερώνεται για όλη τη συνάρτηση, συνολικά, άρα απελευθερώνεται για όλες τις μεταβλητές και τους πίνακες που έχουμε δηλώσει. Δεν χρειάζεται να κάνουμε κάποια ενέργεια.
- Με τη malloc γίνεται άλλη διαχείριση. Υπάρχει ένας ξεχωριστός χώρος συνολικά στο πρόγραμμα (αναφέρεται ως "heap") και όταν κάνουμε malloc δεσμεύεται χώρος από αυτόν (και όχι από το χώρο της συνάρτησης) και διατηρείται δεσμευμένος ανεξάρτητα από τις συναρτήσεις που δημιουργούνται και ολοκληρώνονται. Συνεπώς είναι προγραμματιστική μας ευθύνη να κάνουμε σωστή διαχείριση του heap και να απελευθερώνουμε το χώρο, όταν δεν τον χρειαζόμαστε πια.
@@psounis ευχαριστώ πολυ
Καλησπέρα, στην αρχή του βίντεο οι διευθύνσεις pin[0] ,pin[1], pin[2] κλπ δεν θα έπρεπε να έχουν διάφορα μεταξύ τους 4 θέσεις στην μνήμη αφού τις δηλώνουμε ως Int;Το Pin[0][0] από το pin[0][1] κλπ μου το βγάζει κανονικά ανά 4 θέσεις ενώ το pin[0] ,pin[1], pin[2] ανά 8 θέσεις.
Κάθε στοιχείο pin[0], pin[1] κ.λπ. είναι δείκτης σε ακέραιο, που πιάνει 8 θέσεις στη μνήμη.
στην εντολή printf("%2d",p[i] [j]) το 2 κάνει την ίδια δουλειά με το %t; δηλαδή κάνει τα κενά;
Ναι, αλλά να μην πούμε την ίδια με το \t, γιατί είναι διαφορετική η λειτουργία τους. Περισσότερα εδώ: ua-cam.com/video/7E7mQXUDEuE/v-deo.html
Πότε μπορεί να αποτύχει η malloc;
Γενικά όταν δεν μπορεί να δεσμευτεί το μπλοκ που ζητάμε. Σε δύο περιπτώσεις:
α/ π.χ. ζητάμε κάτι πολύ μεγάλο, ας πούμε 10.000.000.000 bytes (10 gb) και ο υπολογιστής δεν έχει τόση μνήμη
β/ Η μνήμη έχει δεσμευτεί από άλλα προγράμματα και το λειτουργικό στο οποίο διοχετεύουμε το αίτημα, το αρνείται μιας και δεν μπορεί να βρει τέτοιο μπλοκ μνήμης ελεύθερο.
Καλησπέρα δάσκαλε, έχω παρατηρήσει (εάν εφαρμόζω σωστά αυτά που λέτε) ότι η malloc προσπαθεί να "βάλει" τους μονοδιάστατους πίνακες σε σειρά στην μνήμη χωρίς αυτό να είναι αναγκαίο πάντα. Όταν αυτό συμβαίνει βλέπω ότι ανάμεσα στις "γραμμές" ανάλογα τον IDE που χρησιμοποιώ (VS code / Dev C++) υπάρχει ένα "κενό" συνήθως 12 bytes στον 1ον και 28 στον 2ο αντίσοιχα. Έψαξα στο stackoverflow και νομίζω βρήκα παρόμοιο post stackoverflow.com/questions/15300901/c-programming-2d-array-malloc-interesting-values-after-every-row-seek-explana.
Σε περίπτωση που βγάζουν νόημα τα παραπάνω θέλω να ρωτήσω 2 πράγματα:
1ον) Στην περίπτωση που η μια γραμμή είναι σε εντελώς "άσχετη" θέση με τις υπόλοιπες, δεν αποτελεί κάποιον κίνδυνο αυτό για την λειτουργία του προγράμματος ή για την οργάνωση των δεδομένων μας στη μνήμη;
2ον) Πρέπει να γνωρίζουμε για αυτά τα bytes ανάμεσα στις γραμμές ή είναι κάτι το οποίο δεν μπορεί να επηρεάσει το πρόγραμμά μας;
Πολύ ωραία, εμπλούτισες και τις γνώσεις μου ;-) Αυτές τις λεπτομέρειες που έχει το εκτενές άρθρο δεν τις είχα υπόψη...
Αυτό που πρέπει να πω είναι ότι γνωρίζοντας ότι κάθε malloc δεσμεύει κάποιο χώρο χωρίς να προσδιορίζουμε εμείς ακριβώς ποιος θα είναι, αλλά πόσα bytes θα είναι και με βάση το γεγονός ότι εδώ κάνουμε Ν+1 διαφορετικά malloc, έπεται ότι μπορούν να είναι οπουδήποτε στη μνήμη και όχι σε διαδοχικές θέσεις.
Γιατί όμως να είναι πρόβλημα αυτό; Αφού όταν γράφουμε π.χ. array[i][j] πάει πρώτα στο array και βρίσκει τον πίνακα δεικτών, έπειτα στο array[i] για να βρει τη γραμμή και έπειτα στο array[i][j] που είναι πλέον το συγκεκριμένο στοιχείο. Συνεπώς με τη συνηθισμένη χρήση που κάνουμε, αυτές οι λεπτομέρειες δεν μας αφορούν στην πράξη, αλλά απλά γίνονται στο παρασκήνιο.
Τέλος, για τη 2η ερώτηση, δεν βλέπω κανέναν καλό λόγο, ιδίως στο επίπεδο που είμαστε, να γνωρίζουμε κάτι γι' αυτά. Αν γίνουμε δορυφορικοί world-experts στη C τότε ναι (αλλά πιστεύω μόνο σε τέτοιο επίπεδο) θα ήταν χρήσιμο κάτι σαν κι αυτό..
Κατάλαβα τι εννοείτε, ευχαριστώ πολύ για την άμεση απάντηση!
Βαζω τον κωδικα σας και μου πεταει λαθος στην γραμμη 16. Λεει οτι εχει μη εγκυρη αλλαγη απο void* σε int*
Κάποιο θέμα θα έχει ο μεταγλωττιστής που χρησιμοποιείς, προσπάθησε το με ρητό casting:
/* Dynamiki Desmeysi mnimis */
p=(int **)malloc(sizeof(int*)*M);
if (!p)
{
printf("Adynamia desmeusis mnimis");
exit(0);
}
for (i=0; i
Και σε εμενα παρουσιαζει ακριβως το ιδιο προβλημα
το τμημα του κωδικα που ελεγχει την δεσμευση μνημνης και εκτυπωνει την τυχουσα αδυναμια δεσμευση μνημης θα μπορουσε να ειναι μια συναρτηση που να καλειται και να μην γραφουμε το if(!p)... καθε φορα΄;
Ναι βεβαίως, θα μπορούσε κάποιος να το κάνει αυτό, ιδίως αν στο πρόγραμμά του κάνει αυτόν τον έλεγχο πολλές φορές.
@@kavourakos otan kaneis malloc tha prepei na to grapsis etsi (giati einai allh ekdosh metaglotisth ) int **arr = (int **)malloc(M * sizeof(int *)); (gia na diloseis oti thes enan pointer na desmeusei xwro gia alloys pointer )
enw otan thes gia kathe pointer na desmeusei xwro gia akaireous kanei se ena loop arr[i]=(int*)malloc(N*sizeof(int));
afou to arr[i] einai sthn ousia enas dikths !!! elpizw na boithisa