Πώς να ανιχνεύσετε διαρροές μνήμης σε C/C++ με το Valgrind

Pos Na Anichneusete Diarroes Mnemes Se C C Me To Valgrind



Το Valgrind είναι ένα ευρέως χρησιμοποιούμενο εργαλείο για τον εντοπισμό σφαλμάτων και το προφίλ των προγραμμάτων λογισμικού που είναι κυρίως γραμμένα σε C, C++ και άλλες γλώσσες. Βοηθά τους προγραμματιστές να ανιχνεύσουν διαρροές μνήμης, να εντοπίσουν τα σφάλματα πρόσβασης στη μνήμη και να προφίλ την εκτέλεση των προγραμμάτων τους.

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

Διαρροές μνήμης σε C++

Είναι σημαντικό να σημειωθεί ότι το Valgrind έχει σχεδιαστεί κυρίως για προγράμματα C και C++ και ενδέχεται να μην λειτουργεί τόσο αποτελεσματικά με άλλες γλώσσες ή σε όλα τα σενάρια. Επιπλέον, η εκτέλεση ενός προγράμματος υπό το Valgrind μπορεί να επιβραδύνει σημαντικά την εκτέλεσή του, επομένως χρησιμοποιείται συχνά κατά την ανάπτυξη και τον εντοπισμό σφαλμάτων και όχι σε περιβάλλοντα παραγωγής.







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



Εγκατάσταση Valgrid

Για να εγκαταστήσετε το Valgrind σε ένα σύστημα Linux, ανοίξτε ένα τερματικό και ενημερώστε τα αποθετήρια πακέτων σας χρησιμοποιώντας τον διαχειριστή πακέτων που είναι συγκεκριμένος για τη διανομή Linux σας. Η ακόλουθη εντολή λειτουργεί για συστήματα που βασίζονται στο Ubuntu και στο Debian:



$ sudo εύστοχη ενημέρωση

Χρησιμοποιήστε τη διαχείριση πακέτων για να εγκαταστήσετε το Valgrind. Και πάλι, η εντολή μπορεί να διαφέρει ανάλογα με τη διανομή Linux σας. Χρησιμοποιήστε την ακόλουθη εντολή για συστήματα που βασίζονται στο Ubuntu και στο Debian:





$ sudo κατάλληλος εγκαθιστώ πύλη εκλογών

Όταν σας ζητηθεί, εισαγάγετε τον κωδικό πρόσβασης χρήστη και πατήστε 'Enter'. Σημειώστε ότι ο λογαριασμός χρήστη σας χρειάζεται δικαιώματα διαχειριστή για την εγκατάσταση του λογισμικού. Ο διαχειριστής πακέτων κατεβάζει και εγκαθιστά το Valgrind μαζί με τυχόν απαραίτητες εξαρτήσεις. Η διαδικασία μπορεί να διαρκέσει μερικά λεπτά.



Αφού ολοκληρωθεί η διαδικασία εγκατάστασης, μπορείτε να επιβεβαιώσετε την επιτυχή εγκατάσταση του Valgrind εκτελώντας την ακόλουθη εντολή ως βήμα επαλήθευσης:

$ πύλη εκλογών --εκδοχή

Αυτή η εντολή εμφανίζει τις πληροφορίες έκδοσης του Valgrind εάν εγκατασταθεί με επιτυχία.

Αυτό είναι! Το Valgrind θα πρέπει τώρα να εγκατασταθεί στο σύστημά σας Linux και μπορείτε να το χρησιμοποιήσετε για να αναλύσετε και να διορθώσετε τα προγράμματα C/C++ για διαρροές μνήμης και άλλα ζητήματα.

Δημιουργία αρχείου στο Ubuntu

Για να ξεκινήσουμε να εργαζόμαστε στο πρόγραμμα, πρέπει πρώτα να δημιουργήσουμε ένα αρχείο στο Ubuntu. Για τη δημιουργία αρχείων, χρησιμοποιούμε τον επεξεργαστή κειμένου nano. Έτσι, γράφουμε την εντολή στο τερματικό ως εξής:

$ νανο αρχείο 1

Εδώ, nano είναι το όνομα του επεξεργαστή κειμένου που εκτελείται. Το όρισμα 'file1' αντιπροσωπεύει το όνομα του αρχείου που σκοπεύετε να ανοίξετε ή να δημιουργήσετε χρησιμοποιώντας το πρόγραμμα επεξεργασίας κειμένου nano. Το Nano ανοίγει το αρχείο για επεξεργασία εάν υπάρχει ήδη. Εάν όχι, δημιουργεί ένα νέο αρχείο με το παρεχόμενο όνομα. Εφόσον δεν έχουμε τέτοιο αρχείο, δημιουργεί ένα νέο έγγραφο με το όνομα, “file1”.

Μόλις εκτελέσετε την εντολή, θα ανοίξει ο nano editor, παρέχοντάς σας έναν κενό καμβά για να εισαγάγετε ή να επεξεργαστείτε το περιεχόμενο του αρχείου 'file1'. Μπορείτε να ξεκινήσετε να πληκτρολογείτε ή να επικολλάτε το υπάρχον περιεχόμενο στο πρόγραμμα επεξεργασίας.

Τώρα που έχουν επιτευχθεί όλες οι προϋποθέσεις, δημιουργούμε μερικά παραδείγματα για τη χρήση του Valgrind για τον εντοπισμό διαρροών μνήμης σε προγράμματα C++.

Παράδειγμα 1:

Το πρώτο παράδειγμα που παρέχουμε δείχνει ένα απλό παράδειγμα δυναμικής εκχώρησης μνήμης χρησιμοποιώντας τη συνάρτηση 'malloc' από τη βιβλιοθήκη στο C.

#include

ενθ κύριος ( )

{

απανθρακώνω * ένα = malloc ( 102 ) ;

ΕΠΙΣΤΡΟΦΗ 0 ;

}

Ακολουθεί μια ανάλυση του κώδικα:

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

Η γραμμή int main() δηλώνει την κύρια συνάρτηση. Στη συνέχεια, το char *a = malloc(102); δηλώνει μια μεταβλητή δείκτη «a» τύπου char* (δείκτης σε char). Χρησιμοποιεί τη συνάρτηση 'malloc' για να εκχωρήσει δυναμικά τη μνήμη για έναν πίνακα 102 στοιχείων χαρακτήρες (102 byte συνολικά). Το μέγεθος εκχώρησης μνήμης, εκφρασμένο σε byte, αποστέλλεται ως είσοδος στη συνάρτηση malloc και εξάγει έναν δείκτη στο μπλοκ μνήμης που μόλις δημιουργήθηκε. Στον δείκτη char* 'a' εκχωρείται αυτή η τιμή δείκτη. Τέλος, το 'return 0;' σημαίνει το τέλος της κύριας λειτουργίας.

Εν ολίγοις, αυτός ο κώδικας εκχωρεί δυναμικά τη μνήμη για έναν πίνακα 102 στοιχείων χαρακτήρες χρησιμοποιώντας το 'malloc' και εκχωρεί τη διεύθυνση μνήμης στον δείκτη 'a'. Ωστόσο, σημειώστε ότι ο κώδικας δεν χρησιμοποιεί ούτε χειρίζεται την εκχωρημένη μνήμη με οποιονδήποτε τρόπο και δεν περιλαμβάνει την εκχώρηση της μνήμης με χρήση δωρεάν.

Όταν εκτελούμε αυτό το πρόγραμμα μέσω του Valgrind με την επιλογή “–leak-check=full”, εκτελεί έλεγχο διαρροής μνήμης και παρέχει μια αναφορά εξόδου.

Η αναφορά εξόδου που παράγεται από τη Valgrid δίνεται ως εξής:

Παράδειγμα 2:

Για να ξεκινήσουμε με αυτήν την απεικόνιση, δημιουργούμε πρώτα ένα αρχείο 'test2' χρησιμοποιώντας τον επεξεργαστή κειμένου nano όπως εξηγήθηκε προηγουμένως γράφοντας την εντολή:

$ νανο τεστ2

Τώρα, γράφουμε ένα πρόγραμμα C++ για να ελέγξουμε εάν υπάρχει διαρροή μνήμης χρησιμοποιώντας το Valgrind:

#include

#include

#include

const int a_s = 3000 ;

int main ( ) {

ενθ * ia = malloc ( μέγεθος του ( ενθ ) * όπως και ) ;

Για ( int i = 0 ; Εγώ < όπως και; i++ ) {

το [ Εγώ ] = i;

}

srand ( χρόνος ( ΜΗΔΕΝΙΚΟ ) ) ;

int rn = ραντ ( ) % όπως και;

printf ( 'it[%d]: %d \n ' , rn, αυτό [ rn ] ) ;

ΕΠΙΣΤΡΟΦΗ 0 ;

}

Ας περάσουμε από το πρόγραμμα.

Ο κώδικας περιλαμβάνει τα απαραίτητα αρχεία κεφαλίδας και ορίζει τη σταθερή μεταβλητή 'a_s' με τιμή 3000. Μέσα στη συνάρτηση main(), δηλώνεται ένας δείκτης 'ia' τύπου int* και η μνήμη εκχωρείται δυναμικά χρησιμοποιώντας το 'malloc' λειτουργία. Η έκφραση 'sizeof(int) * a_s' καθορίζει τη συνολική απαιτούμενη μνήμη για την αποθήκευση του αριθμού 'a_s' των ακεραίων. Όλα τα στοιχεία του πίνακα 'ia' αρχικοποιούνται από τον βρόχο 'for' με την αντίστοιχη τιμή του δείκτη. Για παράδειγμα, το ia[0] θα είναι 0, το ia[1] θα είναι 1 και ούτω καθεξής.

Η γεννήτρια τυχαίων αριθμών δημιουργείται χρησιμοποιώντας τη συνάρτηση 'srand' χρησιμοποιώντας την τρέχουσα ώρα. Αυτό διασφαλίζει ότι το πρόγραμμα παράγει ένα μοναδικό σύνολο τυχαίων ακεραίων κάθε φορά που εκτελείται. Η συνάρτηση 'rand' δημιουργεί έναν τυχαίο αριθμό και το 'rn' εκχωρείται με το αποτέλεσμα του rand() % a_s. Ο τελεστής συντελεστή '%' περιορίζει το εύρος του τυχαίου αριθμού μεταξύ 0 και a_s – 1 που αντιστοιχεί σε έναν έγκυρο δείκτη εντός του πίνακα 'ia'.

Τέλος, το πρόγραμμα χρησιμοποιεί τη συνάρτηση «printf» για να εκτυπώσει την τιμή στο τυχαία επιλεγμένο ευρετήριο «rn» του πίνακα «ia», μαζί με το αντίστοιχο ευρετήριο.

Όταν εκτελείτε αυτό το πρόγραμμα μέσω του Valgrind, δημιουργεί την ακόλουθη αναφορά εξόδου:

  Ένα στιγμιότυπο οθόνης ενός προγράμματος υπολογιστή Περιγραφή δημιουργήθηκε αυτόματα

συμπέρασμα

Ανακαλύψαμε τη χρήση του εργαλείου Valgrind για τον εντοπισμό των διαρροών μνήμης σε ένα πρόγραμμα C++. Ο οδηγός εγκατάστασης του Valgrind παρέχεται αρχικά. Μετά από αυτό, επεξεργαστήκαμε τη δημιουργία ενός αρχείου στο Ubuntu χρησιμοποιώντας τον επεξεργαστή κειμένου nano. Στο τέλος, χρησιμοποιώντας αυτές τις προϋποθέσεις, εκτελέσαμε δύο παραδείγματα C++ για να ελέγξουμε τις διαρροές μνήμης σε αυτά. Επισυνάπτεται επίσης η αναφορά που δημιουργείται από τη Valgrind, η οποία δείχνει τις διαρροές μνήμης στο παρεχόμενο αρχείο.