1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [Valgrind] 2 00:00:02,000 --> 00:00:05,000 [Nate Hardison, Πανεπιστήμιο Χάρβαρντ] 3 00:00:05,000 --> 00:00:07,000 Αυτό είναι CS50, CS50.TV] 4 00:00:07,000 --> 00:00:10,000 Μερικά από τα πιο δύσκολα σφάλματα σε προγράμματα C 5 00:00:10,000 --> 00:00:13,000 προέρχονται από την κακή διαχείριση της μνήμης. 6 00:00:13,000 --> 00:00:15,000 Υπάρχει ένας τεράστιος αριθμός των τρόπων να βίδα τα πράγματα, 7 00:00:15,000 --> 00:00:17,000 συμπεριλαμβανομένης της κατανομής του λάθος ποσότητα μνήμης, 8 00:00:17,000 --> 00:00:20,000 ξεχνώντας να προετοιμαστεί μεταβλητές, 9 00:00:20,000 --> 00:00:23,000 γραπτώς πριν ή μετά από το τέλος ενός ρυθμιστικού διαλύματος, 10 00:00:23,000 --> 00:00:25,000 και την απελευθέρωση κρατήσει τη μνήμη πολλές φορές. 11 00:00:25,000 --> 00:00:28,000 Τα συμπτώματα κυμαίνονται από απρόβλεπτες διακοπές 12 00:00:28,000 --> 00:00:30,000 μυστηριωδώς να αντικατασταθούν αξίες, 13 00:00:30,000 --> 00:00:34,000 συχνά σε τόπους και χρόνους πολύ μακριά από το αρχικό σφάλμα. 14 00:00:34,000 --> 00:00:37,000 Ιχνηλατώντας την παρατηρούμενη πρόβλημα πίσω με την υποκείμενη αιτία 15 00:00:37,000 --> 00:00:39,000 μπορεί να είναι προκλητική, 16 00:00:39,000 --> 00:00:42,000 αλλά ευτυχώς υπάρχει ένα χρήσιμο πρόγραμμα που ονομάζεται Valgrind 17 00:00:42,000 --> 00:00:44,000 που μπορεί να κάνει πολλά για να βοηθήσει. 18 00:00:44,000 --> 00:00:47,000 >> Μπορείτε να εκτελέσετε ένα πρόγραμμα στο πλαίσιο του Valgrind να ενεργοποιήσετε 19 00:00:47,000 --> 00:00:50,000 εκτενέστερο έλεγχο των κονδυλίων της μνήμης σωρού και προσβάσεις. 20 00:00:50,000 --> 00:00:53,000 Όταν Valgrind εντοπίσει κάποιο πρόβλημα, σας δίνει άμεση, 21 00:00:53,000 --> 00:00:56,000 άμεσες πληροφορίες που σας επιτρέπει να 22 00:00:56,000 --> 00:00:58,000 πιο εύκολα να βρείτε και να διορθώσετε το πρόβλημα. 23 00:00:58,000 --> 00:01:01,000 Valgrind επίσης εκθέσεις για λιγότερο θανατηφόρα θέματα μνήμης, 24 00:01:01,000 --> 00:01:04,000 όπως διαρροές μνήμης, την κατανομή της μνήμης σωρού, 25 00:01:04,000 --> 00:01:07,000 και ξεχνάμε να το ελευθερώσει. 26 00:01:07,000 --> 00:01:10,000 Όπως και compiler μας, Clang, το πρόγραμμα εντοπισμού σφαλμάτων μας, GDB, 27 00:01:10,000 --> 00:01:14,000 Valgrind είναι ελεύθερο λογισμικό, και έχει εγκατασταθεί στη συσκευή. 28 00:01:14,000 --> 00:01:16,000 Valgrind τρέχει σε εκτελέσιμη δυαδική σας, 29 00:01:16,000 --> 00:01:20,000 Δεν σας. ή γ. h αρχεία πηγαίου κώδικα, 30 00:01:20,000 --> 00:01:23,000 έτσι ώστε να είστε σίγουροι ότι έχουν συντάξει ένα up-to-ενημερωμένο αντίγραφο του προγράμματός σας 31 00:01:23,000 --> 00:01:25,000 χρησιμοποιώντας Clang ή Πραγματοποίηση. 32 00:01:25,000 --> 00:01:28,000 Στη συνέχεια, το τρέξιμο κάτω από το πρόγραμμά σας μπορεί να είναι Valgrind 33 00:01:28,000 --> 00:01:32,000 είναι τόσο απλή όσο ακριβώς πρόθεμα το πρότυπο πρόγραμμα με εντολή του Valgrind λέξη, 34 00:01:32,000 --> 00:01:35,000 η οποία ξεκινά Valgrind και τρέχει το πρόγραμμα στο εσωτερικό του. 35 00:01:35,000 --> 00:01:38,000 Κατά την εκκίνηση, Valgrind κάνει κάποια σύνθετη 36 00:01:38,000 --> 00:01:41,000 κοσκινίσεως να ρυθμίσετε το εκτελέσιμο για τους ελέγχους μνήμης, 37 00:01:41,000 --> 00:01:44,000 έτσι ώστε να μπορεί να πάρει λίγο για να ιδρυθεί και να λειτουργήσει. 38 00:01:44,000 --> 00:01:48,000 Το πρόγραμμα στη συνέχεια θα εκτελέσει κανονικά, είναι πολύ πιο αργά, 39 00:01:48,000 --> 00:01:52,000 και όταν τελειώσει, Valgrind θα εκτυπώσετε μια περίληψη της χρήσης της μνήμης. 40 00:01:52,000 --> 00:01:58,000 Αν όλα πάνε καλά, θα δούμε κάτι σαν αυτό: 41 00:01:58,000 --> 00:02:01,000 Σε αυτή την περίπτωση,. / Clean_program 42 00:02:01,000 --> 00:02:04,000 είναι η διαδρομή για το πρόγραμμα που θέλετε να εκτελέσετε. 43 00:02:04,000 --> 00:02:06,000 Και ενώ αυτό δεν λαμβάνει κανένα επιχείρημα, 44 00:02:06,000 --> 00:02:09,000 αν το έκανε Είχα μόλις καρφί για τους μέχρι το τέλος της εντολής, ως συνήθως. 45 00:02:09,000 --> 00:02:12,000 Καθαρίστε το πρόγραμμα είναι απλά ένα ανόητο μικρό πρόγραμμα που δημιούργησα 46 00:02:12,000 --> 00:02:15,000 που διαθέτει χώρο για ένα μπλοκ των ints στο σωρό, 47 00:02:15,000 --> 00:02:19,000 θέσει κάποιες αξίες μέσα τους, και ελευθερώνει το ολόκληρο οικοδομικό τετράγωνο. 48 00:02:19,000 --> 00:02:23,000 Αυτό είναι ό, τι τραβάτε για, χωρίς λάθη και χωρίς διαρροές. 49 00:02:23,000 --> 00:02:27,000 >> Μια άλλη σημαντική μετρική είναι ο συνολικός αριθμός των bytes που διατίθενται. 50 00:02:27,000 --> 00:02:32,000 Ανάλογα με το πρόγραμμα, αν κατανομές σας είναι τα megabytes ή υψηλότερη, 51 00:02:32,000 --> 00:02:34,000 κάνετε πιθανώς κάτι λάθος. 52 00:02:34,000 --> 00:02:37,000 Είσαι άσκοπα την αποθήκευση αντιγράφων; 53 00:02:37,000 --> 00:02:40,000 Χρησιμοποιείτε το σωρό για την αποθήκευση, όταν θα ήταν καλύτερα να χρησιμοποιήσετε τη στοίβα; 54 00:02:40,000 --> 00:02:43,000 Έτσι, τα σφάλματα μνήμης μπορεί να είναι πραγματικά κακό. 55 00:02:43,000 --> 00:02:46,000 Οι πιο εμφανείς αυτές προκαλούν θεαματικά ατυχήματα, 56 00:02:46,000 --> 00:02:49,000 αλλά ακόμα και τότε μπορεί ακόμα να είναι δύσκολο να εντοπιστούν 57 00:02:49,000 --> 00:02:51,000 τι ακριβώς οδήγησε στην συντριβή. 58 00:02:51,000 --> 00:02:54,000 Περισσότερα ύπουλα, ένα πρόγραμμα με ένα σφάλμα μνήμης 59 00:02:54,000 --> 00:02:56,000 μπορούν να εξακολουθούν να συγκεντρώνουν καθαρά 60 00:02:56,000 --> 00:02:58,000 και μπορεί να εξακολουθεί να φαίνεται να λειτουργεί σωστά 61 00:02:58,000 --> 00:03:01,000 γιατί κατάφερε να πάρει τυχερός το μεγαλύτερο μέρος του χρόνου. 62 00:03:01,000 --> 00:03:04,000 Μετά από αρκετές «επιτυχή έκβαση», 63 00:03:04,000 --> 00:03:07,000 μπορείτε να σκεφτείτε ότι ένα κραχ είναι μια απροσδόκητη επιτυχία του υπολογιστή, 64 00:03:07,000 --> 00:03:10,000 αλλά ο υπολογιστής δεν είναι ποτέ λάθος. 65 00:03:10,000 --> 00:03:13,000 >> Τρέχοντας Valgrind μπορεί να σας βοηθήσει να εντοπίσουμε την αιτία των ορατών σφάλματα μνήμης 66 00:03:13,000 --> 00:03:18,000 καθώς και βρείτε κρύβονται τα λάθη δεν χρειάζεται καν γνωρίζουν ακόμη. 67 00:03:18,000 --> 00:03:22,000 Κάθε φορά που Valgrind εντοπίσει κάποιο πρόβλημα, εκτυπώνει τις πληροφορίες σχετικά με το τι παρατηρείται. 68 00:03:22,000 --> 00:03:24,000 Κάθε στοιχείο είναι αρκετά λακωνική - 69 00:03:24,000 --> 00:03:27,000 η γραμμή πηγή της παράνομης διδασκαλίας, ποιο είναι το θέμα, 70 00:03:27,000 --> 00:03:30,000 και μια μικρή πληροφορίες σχετικά με τη μνήμη που εμπλέκονται - 71 00:03:30,000 --> 00:03:34,000 αλλά συχνά είναι αρκετές πληροφορίες για να κατευθύνουν την προσοχή σας στο σωστό μέρος. 72 00:03:34,000 --> 00:03:37,000 Εδώ είναι ένα παράδειγμα του Valgrind τρέχει σε ένα αμαξάκι πρόγραμμα 73 00:03:37,000 --> 00:03:40,000 που κάνει μια έγκυρη ανάγνωση της μνήμης σωρού. 74 00:03:40,000 --> 00:03:49,000 Θα δείτε δεν υπάρχουν σφάλματα ή προειδοποιήσεις σε σύνταξη. 75 00:03:49,000 --> 00:03:53,000 Ωχ, η περίληψη σφάλμα λέει ότι υπάρχουν δύο λάθη - 76 00:03:53,000 --> 00:03:56,000 δύο άκυρα διαβάσει μεγέθους 4 - bytes, αυτό είναι. 77 00:03:56,000 --> 00:04:01,000 Τόσο κακό διαβάζει συνέβη στην κύρια λειτουργία του invalid_read.c, 78 00:04:01,000 --> 00:04:04,000 η πρώτη επί της γραμμής 16 και το δεύτερο επί της γραμμής 19. 79 00:04:04,000 --> 00:04:06,000 Ας δούμε τον κώδικα. 80 00:04:06,000 --> 00:04:11,000 Μοιάζει με την πρώτη πρόσκληση για την printf προσπαθεί να διαβάσει ένα int πέρα ​​από το τέλος του μπλοκ μνήμης μας. 81 00:04:11,000 --> 00:04:13,000 Αν κοιτάξουμε πίσω στην έξοδο του Valgrind, 82 00:04:13,000 --> 00:04:16,000 βλέπουμε ότι Valgrind μας είπε ακριβώς αυτό. 83 00:04:16,000 --> 00:04:19,000 Η διεύθυνση προσπαθούμε να διαβάσετε ξεκινά 0 bytes 84 00:04:19,000 --> 00:04:22,000 μετά το τέλος του μπλοκ του μεγέθους 16 bytes - 85 00:04:22,000 --> 00:04:25,000 τέσσερις 32-bit ints που διατίθενται. 86 00:04:25,000 --> 00:04:29,000 Δηλαδή, η διεύθυνση προσπαθούσαμε να διαβάσετε ξεκινά αμέσως μετά το τέλος του μπλοκ μας, 87 00:04:29,000 --> 00:04:32,000 όπως βλέπουμε σε κακή printf κλήση μας. 88 00:04:32,000 --> 00:04:36,000 Τώρα, το έχουν διαβάσει άκυρο μπορεί να μην φαίνεται σαν αυτό το μεγάλο ζήτημα, 89 00:04:36,000 --> 00:04:39,000 αλλά αν χρησιμοποιείτε αυτά τα δεδομένα για να ελέγχουν τη ροή του προγράμματός σας - 90 00:04:39,000 --> 00:04:42,000 για παράδειγμα, ως μέρος του μια δήλωση ή αν βρόχο - 91 00:04:42,000 --> 00:04:45,000 τότε τα πράγματα μπορούν να πάνε άσχημα σιωπηλά. 92 00:04:45,000 --> 00:04:47,000 Παρακολουθήστε πώς μπορώ να τρέξω το πρόγραμμα invalid_read 93 00:04:47,000 --> 00:04:50,000 και τίποτα από το συνηθισμένο συμβαίνει. 94 00:04:50,000 --> 00:04:52,000 Scary, ε; 95 00:04:52,000 --> 00:04:56,000 >> Τώρα, ας ρίξουμε μια ματιά σε μερικά περισσότερα είδη των λαθών που ενδέχεται να συναντήσετε τον κωδικό σας, 96 00:04:56,000 --> 00:04:59,000 και θα δούμε πώς Valgrind τους εντοπίζει. 97 00:04:59,000 --> 00:05:01,000 Είδαμε μόνο ένα παράδειγμα μιας invalid_read, 98 00:05:01,000 --> 00:05:04,000 έτσι και τώρα ας ελέγξει έξω μια invalid_write. 99 00:05:04,000 --> 00:05:09,000 Και πάλι, δεν υπάρχουν σφάλματα ή προειδοποιήσεις στη σύνταξη. 100 00:05:09,000 --> 00:05:12,000 Εντάξει, Valgrind λέει ότι υπάρχουν δύο λάθη σε αυτό το πρόγραμμα - 101 00:05:12,000 --> 00:05:15,000 και invalid_write και invalid_read. 102 00:05:15,000 --> 00:05:18,000 Ας ελέγξουμε έξω αυτόν τον κώδικα. 103 00:05:18,000 --> 00:05:21,000 Φαίνεται πως έχουμε ένα παράδειγμα του κλασικού strlen συν ένα bug. 104 00:05:21,000 --> 00:05:24,000 Ο κώδικας δεν malloc ένα επιπλέον byte του χώρου 105 00:05:24,000 --> 00:05:26,000 για το χαρακτήρα / 0, 106 00:05:26,000 --> 00:05:30,000 έτσι όταν str αντίγραφο πήγε να το γράψετε σε ssubstrlen "CS50 βράχια!" 107 00:05:30,000 --> 00:05:33,000 έγραψε 1 byte μετά το τέλος του μπλοκ μας. 108 00:05:33,000 --> 00:05:36,000 Η invalid_read έρχεται όταν κάνουμε κλήση μας να printf. 109 00:05:36,000 --> 00:05:40,000 Printf καταλήγει ανάγνωση άκυρο μνήμης όταν διαβάζει το / 0 χαρακτήρα 110 00:05:40,000 --> 00:05:43,000 όπως φαίνεται στο τέλος αυτής της σειράς E είναι η εκτύπωση. 111 00:05:43,000 --> 00:05:45,000 Αλλά τίποτα από αυτά δεν διέφυγε Valgrind. 112 00:05:45,000 --> 00:05:48,000 Βλέπουμε ότι έπιασε το invalid_write ως μέρος του αντιγράφου str 113 00:05:48,000 --> 00:05:51,000 στη γραμμή 11 από τα κύρια, και η invalid_read είναι μέρος της printf. 114 00:05:51,000 --> 00:05:54,000 Ροκ για, Valgrind. 115 00:05:54,000 --> 00:05:57,000 Και πάλι, αυτό μπορεί να μην φαίνεται σαν μια μεγάλη υπόθεση. 116 00:05:57,000 --> 00:06:00,000 Μπορούμε να τρέξει αυτό το πρόγραμμα ξανά και ξανά έξω από Valgrind 117 00:06:00,000 --> 00:06:03,000 και δεν βλέπω κανένα σύμπτωμα σφάλματος. 118 00:06:03,000 --> 00:06:06,000 >> Ωστόσο, ας ρίξουμε μια ματιά σε μια ελαφρά παραλλαγή του αυτό για να δείτε 119 00:06:06,000 --> 00:06:09,000 πώς τα πράγματα μπορούν να πάρουν πραγματικά άσχημη. 120 00:06:09,000 --> 00:06:14,000 Έτσι, παρέχεται, είμαστε κατάχρηση πράγματα περισσότερο από ό, τι ακριβώς λίγο σε αυτόν τον κώδικα. 121 00:06:14,000 --> 00:06:17,000 Είμαστε μόνο τη διάθεση χώρου για την σωρό για δύο χορδές 122 00:06:17,000 --> 00:06:19,000 το μήκος του CS50 βράχους, 123 00:06:19,000 --> 00:06:22,000 αυτή τη φορά, θυμάται ο / 0 χαρακτήρα. 124 00:06:22,000 --> 00:06:25,000 Αλλά τότε ρίχνουμε σε ένα σούπερ-μακρά σειρά μέσα στο μπλοκ μνήμης 125 00:06:25,000 --> 00:06:27,000 S που δείχνει να. 126 00:06:27,000 --> 00:06:30,000 Τι συνέπειες θα έχει για το μπλοκ μνήμης που δείχνει T; 127 00:06:30,000 --> 00:06:34,000 Λοιπόν, αν Τ σημεία στη μνήμη που είναι ακριβώς δίπλα στο S, 128 00:06:34,000 --> 00:06:37,000 έρχεται αμέσως μετά από αυτό, 129 00:06:37,000 --> 00:06:39,000 τότε θα μπορούσαμε να είχαμε γράψει πάνω μέρος του Τ. 130 00:06:39,000 --> 00:06:41,000 Ας εκτελέσετε αυτόν τον κώδικα. 131 00:06:41,000 --> 00:06:43,000 Κοιτάξτε τι συνέβη. 132 00:06:43,000 --> 00:06:47,000 Οι χορδές που αποθηκεύονται σε μπλοκ σωρού μας δύο φαίνεται να έχουν εκτυπωθεί σωστά. 133 00:06:47,000 --> 00:06:49,000 Τίποτα δεν φαίνεται καθόλου λάθος. 134 00:06:49,000 --> 00:06:52,000 Ωστόσο, ας πάμε πίσω στον κώδικα μας και 135 00:06:52,000 --> 00:06:55,000 σχόλιο από τη γραμμή όπου θα αντιγράψετε CS50 βράχους 136 00:06:55,000 --> 00:06:59,000 στο δεύτερο μπλοκ μνήμης, επεσήμανε από την t. 137 00:06:59,000 --> 00:07:02,000 Τώρα, όταν θα εκτελέσετε αυτόν τον κώδικα θα πρέπει να 138 00:07:02,000 --> 00:07:06,000 μόνο να δείτε τα περιεχόμενα του πρώτου μπλοκ μνήμης εκτυπώσετε. 139 00:07:06,000 --> 00:07:09,000 Πω πω, ακόμα κι αν δεν str αντίγραφο 140 00:07:09,000 --> 00:07:12,000 τυχόν χαρακτήρες στο δεύτερο μπλοκ σωρού, ο ένας δείχνεται από Τ, 141 00:07:12,000 --> 00:07:15,000 θα πάρετε μια εκτύπωση. 142 00:07:15,000 --> 00:07:18,000 Πράγματι, το string που γεμιστές σε πρώτο μπλοκ μας 143 00:07:18,000 --> 00:07:21,000 υπερέβη την πρώτη ομάδα και εντός του δεύτερου μπλοκ, 144 00:07:21,000 --> 00:07:23,000 κάνει ό, τι φαίνεται φυσιολογικό. 145 00:07:23,000 --> 00:07:26,000 Valgrind, όμως, μας λέει την αληθινή ιστορία. 146 00:07:26,000 --> 00:07:28,000 Εκεί πάμε. 147 00:07:28,000 --> 00:07:32,000 Όλα αυτά άκυρη διαβάζει και γράφει. 148 00:07:32,000 --> 00:07:36,000 >> Ας δούμε ένα παράδειγμα από ένα άλλο είδος του λάθους. 149 00:07:36,000 --> 00:07:39,000 Εδώ κάνουμε κάτι μάλλον ατυχής. 150 00:07:39,000 --> 00:07:41,000 Θα αρπάξει χώρος για έναν int στο σωρό, 151 00:07:41,000 --> 00:07:45,000 και να προετοιμάσει ένα δείκτη int - p - να επισημάνω σε αυτό το διάστημα. 152 00:07:45,000 --> 00:07:48,000 Ωστόσο, ενώ ο δείκτης μας έχει προετοιμαστεί, 153 00:07:48,000 --> 00:07:52,000 τα στοιχεία ότι είναι δείχνει να έχει μόνο σκουπίδια, τιδήποτε είναι σε αυτό το μέρος του σωρού. 154 00:07:52,000 --> 00:07:55,000 Έτσι, όταν έχουμε φορτώσει τα δεδομένα σε int i, 155 00:07:55,000 --> 00:07:57,000 έχουμε προετοιμαστεί i τεχνικά, 156 00:07:57,000 --> 00:08:00,000 αλλά το κάνουμε με τα δεδομένα σκουπίδια. 157 00:08:00,000 --> 00:08:03,000 Η κλήση για να διεκδικήσει, η οποία είναι μια εύχρηστη μακρο αποσφαλμάτωσης 158 00:08:03,000 --> 00:08:06,000 ορίζεται στο εύστοχα ονομάστηκε διεκδικήσει βιβλιοθήκη, 159 00:08:06,000 --> 00:08:09,000 θα διακόψει το πρόγραμμα εάν η κατάστασή του τεστ αποτύχει. 160 00:08:09,000 --> 00:08:11,000 Δηλαδή, αν δεν είναι 0. 161 00:08:11,000 --> 00:08:14,000 Ανάλογα με το τι έγινε στο χώρο σωρό, επεσήμανε από p, 162 00:08:14,000 --> 00:08:18,000 το πρόγραμμα αυτό θα μπορούσε να λειτουργήσει και μερικές φορές αποτυγχάνουν σε άλλες χρονικές στιγμές. 163 00:08:18,000 --> 00:08:20,000 Αν δουλέψει, είμαστε απλά τυχεροί. 164 00:08:20,000 --> 00:08:24,000 Ο compiler δεν θα πιάσει αυτό το σφάλμα, αλλά Valgrind ότι βούληση. 165 00:08:24,000 --> 00:08:28,000 Εκεί βλέπουμε το σφάλμα που απορρέουν από τη χρήση των εν λόγω δεδομένων σκουπίδια. 166 00:08:28,000 --> 00:08:32,000 >> Όταν εκχώρηση μνήμης σωρού, αλλά δεν το deallocate ή ελευθερώνετε, 167 00:08:32,000 --> 00:08:34,000 που ονομάζεται διαρροή. 168 00:08:34,000 --> 00:08:37,000 Για μια μικρή, βραχύβια πρόγραμμα που τρέχει και αμέσως εξόδους, 169 00:08:37,000 --> 00:08:39,000 διαρροές είναι αρκετά αβλαβή, 170 00:08:39,000 --> 00:08:42,000 αλλά για ένα έργο του μεγαλύτερου μεγέθους ή / και τη μακροζωία, 171 00:08:42,000 --> 00:08:46,000 ακόμη και μια μικρή διαρροή μπορεί να επιδεινώνει σε κάτι σημαντικό. 172 00:08:46,000 --> 00:08:49,000 Για CS50, εμείς αναμένουμε από εσάς να 173 00:08:49,000 --> 00:08:51,000 να φροντίζει για την απελευθέρωση όλων των μνήμη του σωρού που διαθέτουν, 174 00:08:51,000 --> 00:08:54,000 επειδή θέλουμε να οικοδομήσουμε τις δεξιότητες για να χειριστεί σωστά τη χειροκίνητη διαδικασία 175 00:08:54,000 --> 00:08:56,000 που απαιτούνται από τον C. 176 00:08:56,000 --> 00:08:59,000 Για να γίνει αυτό, το πρόγραμμά σας θα πρέπει να έχουμε μια ακριβή 177 00:08:59,000 --> 00:09:03,000 ένα-προς-ένα αντιστοιχία μεταξύ malloc και δωρεάν κλήσεις. 178 00:09:03,000 --> 00:09:06,000 Ευτυχώς, Valgrind μπορεί να σας βοηθήσει με τις διαρροές μνήμης πάρα πολύ. 179 00:09:06,000 --> 00:09:09,000 Εδώ είναι ένα πρόγραμμα που ονομάζεται διαρροή leak.c που διαθέτει 180 00:09:09,000 --> 00:09:13,000 χώρο στο σωρό, γράφει σε αυτό, αλλά δεν το απελευθερώσει. 181 00:09:13,000 --> 00:09:16,000 Εμείς το υπολογίσουν με κάνει και να τρέξει κάτω από το Valgrind, 182 00:09:16,000 --> 00:09:18,000 και βλέπουμε ότι, ενώ δεν έχουμε σφάλματα μνήμης, 183 00:09:18,000 --> 00:09:20,000 έχουμε μία διαρροή. 184 00:09:20,000 --> 00:09:23,000 Υπάρχουν 16 bytes σίγουρα χαθεί, 185 00:09:23,000 --> 00:09:27,000 πράγμα που σημαίνει ότι ο δείκτης σε αυτή την μνήμη δεν ήταν σε έκταση, όταν βγήκε το πρόγραμμα. 186 00:09:27,000 --> 00:09:30,000 Τώρα, Valgrind δεν μας δίνει έναν τόνο των πληροφοριών σχετικά με τη διαρροή, 187 00:09:30,000 --> 00:09:35,000 αλλά αν ακολουθήσουμε αυτό το μικρό σημείωμα που δίνει κάτω προς το κάτω μέρος της έκθεσής της 188 00:09:35,000 --> 00:09:38,000 να επαναπροσδιορίζονται με - διαρροή-check = πλήρη 189 00:09:38,000 --> 00:09:41,000 για να δείτε τα πλήρη στοιχεία της μνήμης που διέρρευσαν, 190 00:09:41,000 --> 00:09:44,000 θα πάρουμε περισσότερες πληροφορίες. 191 00:09:44,000 --> 00:09:46,000 Τώρα, στην περίληψη σωρό, 192 00:09:46,000 --> 00:09:50,000 Valgrind μας λέει όπου η μνήμη που χάθηκε αρχικά κατανεμηθεί. 193 00:09:50,000 --> 00:09:52,000 Όπως γνωρίζουμε από την αναζήτηση στον πηγαίο κώδικα, 194 00:09:52,000 --> 00:09:55,000 Valgrind μας πληροφορεί ότι διέρρευσε την μνήμη 195 00:09:55,000 --> 00:09:58,000 κατανέμονται με μια πρόσκληση για malloc στη γραμμή 8 του leak.c 196 00:09:58,000 --> 00:10:00,000 στην κύρια λειτουργία. 197 00:10:00,000 --> 00:10:02,000 Αρκετά ικανό. 198 00:10:02,000 --> 00:10:04,000 >> Valgrind κατηγοριοποιεί τις διαρροές χρησιμοποιώντας αυτούς τους όρους: 199 00:10:04,000 --> 00:10:07,000 Σίγουρα έχασε - αυτό είναι σωρός διατεθεί μνήμη 200 00:10:07,000 --> 00:10:10,000 για τις οποίες το πρόγραμμα δεν έχει πλέον ένα δείκτη. 201 00:10:10,000 --> 00:10:14,000 Valgrind ξέρει ότι είχατε μια φορά το δείκτη, αλλά από τότε έχουν χάσει τα ίχνη του. 202 00:10:14,000 --> 00:10:17,000 Αυτή η μνήμη είναι σίγουρα διαρρεύσει. 203 00:10:17,000 --> 00:10:20,000 Έμμεσα χαθεί - αυτό είναι σωρός διατεθεί μνήμη 204 00:10:20,000 --> 00:10:24,000 στο οποίο οι μόνες δείκτες σε επίσης χάνονται. 205 00:10:24,000 --> 00:10:27,000 Για παράδειγμα, αν έχετε χάσει το δείκτη του ποντικιού στο πρώτο κόμβο της λίστας που συνδέονται, 206 00:10:27,000 --> 00:10:30,000 τότε ο πρώτος κόμβος καθαυτός θα χαθεί οριστικά, 207 00:10:30,000 --> 00:10:34,000 ενώ τυχόν μεταγενέστερες κόμβοι θα εμμέσως χαθεί. 208 00:10:34,000 --> 00:10:37,000 Ενδεχομένως χαθεί - αυτό είναι σωρός διατεθεί μνήμη 209 00:10:37,000 --> 00:10:41,000 στην οποία Valgrind δεν μπορεί να είναι βέβαιος κατά πόσον υπάρχει ένας δείκτης ή όχι. 210 00:10:41,000 --> 00:10:44,000 Ακόμα είναι προσβάσιμο σωρός διατεθεί μνήμη 211 00:10:44,000 --> 00:10:47,000 με το οποίο το πρόγραμμα εξακολουθεί να έχει ένα δείκτη στην έξοδο, 212 00:10:47,000 --> 00:10:50,000 που συνήθως σημαίνει ότι μια καθολική μεταβλητή σημεία σε αυτό. 213 00:10:50,000 --> 00:10:53,000 Για να ελέγξετε για διαρροές αυτές, θα πρέπει επίσης να περιλαμβάνει την επιλογή 214 00:10:53,000 --> 00:10:55,000 - Ακόμα-προσβάσιμο = ναι 215 00:10:55,000 --> 00:10:58,000 στην επίκληση της Valgrind σας. 216 00:10:58,000 --> 00:11:01,000 >> Αυτές οι διαφορετικές περιπτώσεις ενδέχεται να απαιτούν διαφορετικές στρατηγικές για τον καθαρισμό τους επάνω, 217 00:11:01,000 --> 00:11:05,000 αλλά διαρροές πρέπει να εξαλειφθούν. 218 00:11:05,000 --> 00:11:08,000 Δυστυχώς, για τον καθορισμό διαρροές μπορεί να είναι δύσκολο να το κάνετε, 219 00:11:08,000 --> 00:11:11,000 από λανθασμένες κλήσεις στην ελεύθερη να ανατινάξουν το πρόγραμμά σας. 220 00:11:11,000 --> 00:11:14,000 Για παράδειγμα, αν κοιτάξουμε invalid_free.c, 221 00:11:14,000 --> 00:11:18,000 βλέπουμε ένα παράδειγμα της κακής μνήμης ανακατανομή. 222 00:11:18,000 --> 00:11:21,000 Τι θα πρέπει να είναι μια ενιαία πρόσκληση για να απελευθερώσει ολόκληρο το οικοδομικό τετράγωνο 223 00:11:21,000 --> 00:11:24,000 της μνήμης που υποδεικνύεται από int_block, 224 00:11:24,000 --> 00:11:27,000 έχει γίνει αντ 'αυτού μια προσπάθεια να απελευθερώσει κάθε int μεγέθους τμήμα 225 00:11:27,000 --> 00:11:29,000 της μνήμης ξεχωριστά. 226 00:11:29,000 --> 00:11:32,000 Αυτό θα αποτύχει καταστροφικά. 227 00:11:32,000 --> 00:11:34,000 Boom! Τι λάθος. 228 00:11:34,000 --> 00:11:36,000 Αυτό είναι σίγουρα δεν είναι καλό. 229 00:11:36,000 --> 00:11:39,000 Αν είστε κολλημένοι με αυτό το είδος του λάθους, όμως, και δεν ξέρετε πού να κοιτάξετε, 230 00:11:39,000 --> 00:11:41,000 καταφύγουμε σε νέα καλύτερος φίλος σας. 231 00:11:41,000 --> 00:11:44,000 Σωστά μαντέψατε - Valgrind. 232 00:11:44,000 --> 00:11:47,000 Valgrind, όπως πάντα, ξέρει ακριβώς τι συμβαίνει. 233 00:11:47,000 --> 00:11:50,000 Οι alloc και δωρεάν Η δεν ταιριάζουν. 234 00:11:50,000 --> 00:11:52,000 Έχουμε 1 και 4 alloc ελευθερώνει. 235 00:11:52,000 --> 00:11:55,000 Και Valgrind μας λέει, επίσης, όπου η πρώτη κακή δωρεάν κλήση - 236 00:11:55,000 --> 00:11:58,000 αυτός που προκάλεσε την blowup - έρχεται από - 237 00:11:58,000 --> 00:12:00,000 γραμμή 16. 238 00:12:00,000 --> 00:12:03,000 Όπως μπορείτε να δείτε, η κακή κλήσεις για την απελευθέρωση είναι πραγματικά κακή, 239 00:12:03,000 --> 00:12:05,000 γι 'αυτό προτείνουμε να αφήσει διαρροή πρόγραμμα σας 240 00:12:05,000 --> 00:12:08,000 ενώ εργάζεστε για να πάρει τη σωστή λειτουργικότητα. 241 00:12:08,000 --> 00:12:12,000 Αρχίσετε να ψάχνετε για διαρροές μόνο μετά το πρόγραμμά σας λειτουργεί σωστά, 242 00:12:12,000 --> 00:12:14,000 χωρίς άλλα λάθη. 243 00:12:14,000 --> 00:12:16,000 >> Και αυτό είναι ό, τι έχουμε για αυτό το βίντεο. 244 00:12:16,000 --> 00:12:18,000 Τώρα τι περιμένεις; 245 00:12:18,000 --> 00:12:21,000 Μετάβαση τρέξει Valgrind στα προγράμματά σας αυτή τη στιγμή. 246 00:12:21,000 --> 00:12:25,000 Το όνομά μου είναι Nate Hardison. Αυτό είναι CS50. [CS50.TV]