[Powered by Google Translate] [Valgrind] [Nate Hardison, ჰარვარდის უნივერსიტეტი] ეს არის CS50, CS50.TV] ზოგიერთი ყველაზე რთული შეცდომებს C პროგრამების მოდის არასწორად მართვაში მეხსიერება. არსებობს დიდი რაოდენობით გზა Screw რამ up, მათ შორის განაწილების არასწორი ოდენობით მეხსიერება, ავიწყდება ინიციალიზაცია ცვლადები, წერის დაწყებამდე ან დასრულების შემდეგ ბუფერული, და ათავისუფლებს შევინარჩუნოთ ხსოვნა რამდენჯერმე. სიმპტომები მერყეობს წყვეტილი დამსხვრევაზე to mysteriously ინსტალერის ღირებულებების, ხშირად ადგილებზე და ჯერ შორს ამოღებულ ორიგინალური შეცდომა. ტრასირება გამოვლენილი პრობლემა თავში ფუძემდებლური ძირეული მიზეზი შეიძლება რთული, მაგრამ საბედნიეროდ არსებობს გამოსადეგი პროგრამა მოუწოდა Valgrind რომ ბევრი დასახმარებლად. თქვენ აწარმოებს პროგრამა Valgrind რომელიც საშუალებას მისცემს ვრცელი შემოწმება ბევრი მეხსიერების გამოყოფის და ხელმისაწვდომი. როდესაც Valgrind ცნობს პრობლემა, ეს გაძლევთ დაუყოვნებლივ, პირდაპირი ინფორმაცია, რომელიც საშუალებას გაძლევთ უფრო ადვილად იპოვოს და დაფიქსირება პრობლემა. Valgrind ასევე მოხსენებებს ნაკლები სასიკვდილო მეხსიერების საკითხებს, როგორიცაა მეხსიერების ტბები, გამოყოფის ბევრი მეხსიერება, და ავიწყდება გასათავისუფლებლად იგი. არა ჩვენი შემდგენელი, Clang, ჩვენს debugger, GDB, Valgrind არის თავისუფალი პროგრამა, და იგი დამონტაჟებული ელექტრო მოწყობილობების. Valgrind ეშვება თქვენი ორობითი შესრულებადი, არ არის თქვენი. გ ან. თ კოდის ფაილი ასე დარწმუნდით, რომ არ შედგენილი up-to-date ასლი თქვენი პროგრამა გამოყენებით Clang ან ჩადება. მაშინ, გაშვებული თქვენი პროგრამა Valgrind შეიძლება იყოს იმდენად მარტივია, უბრალოდ prefixing სტანდარტული პროგრამა ბრძანება ერთად სიტყვა Valgrind, რომელიც იწყება up Valgrind და ეშვება პროგრამა შიგნით მას. როდესაც დაწყებული, Valgrind აკეთებს ზოგიერთი კომპლექსი jiggering კონფიგურაციის შესრულებადი ამისთვის მეხსიერების ამოწმებს, ამიტომ მას შეუძლია მიიღოს bit მისაღებად შექმნილია და გამართულად მუშაობს. პროგრამა შემდეგ შეასრულოს ნორმალურად, იქნება ეს ბევრად უფრო ნელა, და როდესაც დასრულდება, Valgrind იქნება ბეჭდვა შემაჯამებელი მისი მეხსიერების გამოყენების. თუ ყველაფერი კარგად, იგი გამოიყურება მსგავსი რამ: ამ შემთხვევაში. / Clean_program არის გზა პროგრამის მინდა აწარმოებს. და სანამ ეს ერთი არ იღებს რაიმე არგუმენტები, თუ ეს მოხდა მე უბრალოდ Tack მათ ბოლომდე ბრძანება, როგორც ყოველთვის. სუფთა პროგრამა უბრალოდ სულელური პატარა პროგრამის მე შექმნა რომ გამოყოფს ფართი ბლოკი ints შესახებ ბევრი, დააყენა ზოგიერთი ღირებულებების შიგნით მათ, და ათავისუფლებს მთელი ბლოკი. ეს არის ის, რაც თქვენ სროლა ამისთვის, არ შეცდომები და არ გაჟონვის. კიდევ ერთი მნიშვნელოვანი მეტრულ არის საერთო რაოდენობის ბაიტი გამოყოფილი. დამოკიდებულია პროგრამის, თუ თქვენი დაფინანსებამ არიან მბ ან უფრო მაღალი, თქვენ ალბათ აკეთებს რაღაც. თქვენ ზედმეტად შენახვის დუბლიკატები? თქვენ გამოყენებით ბევრი შენახვის, როდესაც უკეთესი იქნება გამოიყენოს დასტის? ასე რომ, მეხსიერების შეცდომები შეიძლება იყოს ჭეშმარიტად ბოროტების. უფრო აშკარა პირობა გამოიწვიოს სანახაობრივი დამსხვრევაზე, მაგრამ მაშინ ჯერ კიდევ შეუძლია იყოს ძნელი pinpoint რა ზუსტად გამოიწვია კრახი. გაძლიერებული insidiously, პროგრამა მეხსიერების შეცდომა მაინც შეადგინოს cleanly და მაინც, როგორც ჩანს, მუშაობს იმიტომ, რომ თქვენ მოახერხა გაუმართლა ყველაზე მეტად დრო. შემდეგ რამდენიმე "წარმატებული შედეგების" თქვენ ალბათ უბრალოდ ფიქრობთ, რომ არის ავარიის Fluke of კომპიუტერი, მაგრამ კომპიუტერში არასოდეს არ არის არასწორი. Running Valgrind დაგეხმარებათ აკონტროლოთ ქვემოთ მიზეზია ხილული მეხსიერება შეცდომები ასევე მოვძებნოთ lurking შეცდომები თქვენ კი არ გაუკეთებია შესახებ ვიცით. ყოველ ჯერზე Valgrind ცნობს პრობლემა, იგი ბეჭდავს ინფორმაციას, თუ რას დაფიქსირდა. თითოეული პუნქტი საკმაოდ მოკლე - წყარო ხაზი შეურაცხყოფა დავალებით, რა საკითხი, და პატარა ინფორმაცია მეხსიერების ჩართული - მაგრამ ხშირად ეს საკმარისი ინფორმაცია პირდაპირ თქვენს ყურადღებას ადგილას. აქ არის მაგალითი Valgrind გაშვებული buggy პროგრამა რომ არ არასწორი წაკითხული of ბევრი მეხსიერებაში. ჩვენ ვხედავთ შეუცდომლობის ან გაფრთხილებისა წელს კომპილაცია. Uh-oh, შეცდომა შემაჯამებელი ნათქვამია, რომ არსებობს ორი შეცდომები - ორი არასწორი ნათქვამია საქართველოს ზომა 4 - ბაიტი, რომ არის. ორივე ცუდი ნათქვამია მოხდა ძირითადი ფუნქცია invalid_read.c, პირველი on line 16 და მეორე ხაზი 19. მოდით შევხედოთ კოდი. როგორც ჩანს, პირველი ზარი printf ცდილობს წაიკითხა int წარსულში ბოლოს ჩვენი მეხსიერების ბლოკში. თუ ჩვენ ვიხსენებთ Valgrind ის გამომუშავება, ჩვენ ვხედავთ, რომ Valgrind გვითხრა ზუსტად რომ. მისამართი ჩვენ წაკითხვის მცდელობისას იწყება 0 ბაიტი წარსულში ბოლოს ბლოკი ზომა 16 ბაიტი - ოთხი 32-bit ints რომ ჩვენ გამოყოფილი. ანუ, მისამართი ჩვენ წაკითხვის მცდელობისას იწყება უფლება დასასრულს ჩვენი ბლოკის, ისევე როგორც ჩვენ ვხედავთ ჩვენი ცუდი printf ზარი. ახლა, არასწორი ნათქვამია შეიძლება არ ჩანს, რომ ეს ასეა დიდი გარიგება, მაგრამ თუ თქვენ იყენებთ, რომ მონაცემები გაკონტროლება ნაკადის თქვენი პროგრამა - მაგალითად, როგორც ნაწილი იმ შემთხვევაში, თუ განაცხადი ან loop - ყველაფერი ჩუმად წასვლა ცუდი. Watch როგორ შემიძლია აწარმოებს invalid_read პროგრამა და არაფერი არაორდინალურის ხდება. საშინელი, არა? ახლა, მოდით შევხედოთ რამდენიმე სახის შეცდომები, რომ თქვენ შეიძლება ექმნებათ თქვენს კოდი, და ჩვენ დავინახავთ, თუ Valgrind ცნობს მათ. ჩვენ უბრალოდ დაინახა მაგალითი invalid_read, ახლა მოდით შეამოწმეთ invalid_write. ისევ და ისევ, არ შეცდომები ან გაფრთხილებისა წელს კომპილაცია. Okay, Valgrind ნათქვამია, რომ არსებობს ორი შეცდომები ამ პროგრამაში - და invalid_write და invalid_read. მოდით შეამოწმეთ ეს კოდი. როგორც ჩანს, ჩვენ მივიღეთ ინსტანციის კლასიკური strlen პლუს ერთი bug. კოდექსი არ malloc ზედმეტი byte სივრცეში ამისთვის / 0 ხასიათი, ასე რომ, როდესაც ქ ასლი წავიდა დაწერა მას ssubstrlen "cs50 rocks!" იგი წერდა 1 byte წარსულში ბოლოს ჩვენი ბლოკი. Invalid_read მოდის, როდესაც ჩვენ ჩვენი ზარი printf. Printf მთავრდება კითხულობს არასწორი მეხსიერების როდესაც ნათქვამია მოხსენებაში / 0 ხასიათი როგორც ეს უყურებს ბოლომდე E სიმებიანი ეს ბეჭდვა. თუმცა, ეს გაიქცა Valgrind. ჩვენ ვხედავთ, რომ იგი დაიჭირეს invalid_write ნაწილად ქ ასლი on line 11 ძირითადი და invalid_read ნაწილია printf. Rock წლის, Valgrind. ისევ, ეს არ ჩანს როგორც დიდი გარიგება. ჩვენ შეგვიძლია მას მოვთხოვოთ ამ პროგრამის მეტი და მეტი გარეთ Valgrind და ვერ ვხედავთ შეცდომა სიმპტომები. თუმცა, მოდით, შევხედოთ უმნიშვნელო ვარიაცია ამ ვიხილოთ როგორ შეიძლება კიდევ მართლა ცუდია. ასე რომ, მიანიჭა, ჩვენ ბოროტად რამ მეტი, ვიდრე უბრალოდ ცოტა ამ კოდექსში. ჩვენ მხოლოდ გამოყოფის სივრცე ბევრი ორი სიმები სიგრძეზე cs50 კლდეები, ამ დროს, დამახსოვრების / 0 ხასიათი. მაგრამ მაშინ ჩვენ ჩააგდოს წელს სუპერ ხანგრძლივი string შევიდა მეხსიერების ბლოკი რომ არის მიუთითებს. რა ეფექტი ექნება, რომ იქონიოს მეხსიერების ბლოკი, რომ T მიუთითებს? ისე, თუ T რაოდენობა ხსოვნას ეს მხოლოდ მიმდებარე S, მოვდივარ უბრალოდ მას შემდეგ, მაშინ ჩვენ, შესაძლოა, წერილობითი მეტი ნაწილი თ მოდით აწარმოებს ამ კოდი. შეხედეთ რა მოხდა. სიმები ჩვენ შენახული ჩვენი ბევრი ბლოკები ორივე აღმოჩნდა არ დაბეჭდილი სწორად. არაფერი ჩანს არასწორი იყო. თუმცა, მოდით დავუბრუნდეთ ჩვენს კოდი და კომენტარის out ხაზის სადაც ჩვენ კოპირება cs50 კლდეები მეორე მეხსიერების ბლოკი, მიუთითა მიერ ტ. ახლა, როდესაც ჩვენ აწარმოებს ამ კოდი უნდა მხოლოდ ვხედავ შინაარსი პირველი მეხსიერების ბლოკი ამობეჭდოთ. Whoa, მიუხედავად იმისა, რომ ჩვენ არ ქუჩა ასლი ნებისმიერი გმირები მეორე ბევრი ბლოკი, ერთი მიუთითებს მიერ T, მივიღებთ ბეჭდვითი out. მართლაც, string ჩვენ ფუნქციონირებს შევიდა ჩვენი პირველი ბლოკი დაესხა პირველი ბლოკი და მეორე კორპუსი, მიღების ყველაფერი ჩანს ნორმალურია. Valgrind, თუმცა, გვეუბნება ნამდვილი ამბავი. იქ ჩვენ წავიდეთ. ყველა იმ არასწორი ნათქვამია და წერს. მოდით შევხედოთ მაგალითს სხვა სახის შეცდომა. აქ ჩვენ რაღაც საკმაოდ სამწუხაროა. ჩვენ დაიბრუნოს ფართი int შესახებ ბევრი, და ჩვენ ინიციალიზაცია int მიმთითებელი - P - აღვნიშნო, რომ სივრცეში. მიუხედავად იმისა, რომ ჩვენი მაჩვენებელი ინიციალიზდება, მონაცემები, რომ ის მიუთითებს მხოლოდ უკვე რასაც უსარგებლო არის იმ ნაწილში ბევრი. ასე რომ, როდესაც ჩვენ ჩატვირთვა, რომ მონაცემების int i, ჩვენ ტექნიკურად ინიციალიზაცია i, მაგრამ ჩვენ ამისათვის ერთად უსარგებლო მონაცემები. ზარი მტკიცებით, რომელიც მოსახერხებელი გამართვის მაკრო განსაზღვრული aptly დაასახელა ამტკიცებენ ბიბლიოთეკა, პროცესი შეწყვეტილია პროგრამა თუ მისი ტესტი მდგომარეობა ვერ. ანუ, თუ არ არის 0. დამოკიდებულია რა იყო ბევრი სივრცე, მიუთითა მიერ P, ამ პროგრამის შესაძლოა სამუშაო, ხან და ვერ სხვა ჯერ. თუ მუშაობს, ჩვენ უბრალოდ ვიღებთ გაუმართლა. შემდგენელი არ დაიჭიროთ ეს შეცდომა, მაგრამ Valgrind დარწმუნებული ნება. იქ ჩვენ ვხედავთ შეცდომა გამომდინარე ჩვენი გამოყენება, რომ უსარგებლო მონაცემები. როცა გამოყოფს ბევრი მეხსიერების მაგრამ არ deallocate ის ან თავისუფალი მას, რომ ჰქვია გაჟონვის. პატარა, მოკლე ფეხები პროგრამა, რომელიც ეშვება და დაუყოვნებლივ გასასვლელების, გაჟონვის საკმაოდ უვნებელია, მაგრამ პროექტი უფრო დიდი ზომა და / ან დღეგრძელობისა, თუნდაც მცირე გაჟონვის შეიძლება ნაერთის შევიდა რაღაც ძირითადი. იყიდება CS50, ჩვენ ველით, რომ თქვენ იზრუნოს ათავისუფლებს ყველა ბევრი მეხსიერება, რომ თქვენ გამოყოფას, მას შემდეგ, რაც ჩვენ გვინდა თქვენ აშენება უნარი სათანადოდ გაუმკლავდეს მანუალურ პროცესს მოთხოვნილი C. ამისათვის თქვენი პროგრამის უნდა ჰქონდეს ზუსტი ერთი-to-ერთი კორესპონდენცია malloc და თავისუფალი მოუწოდებს. საბედნიეროდ, Valgrind დაგეხმარებათ მეხსიერების გაჟონვის ძალიან. აქ არის leaky პროგრამის მოუწოდა leak.c რომ გამოყოფს სივრცე ბევრი, წერს, მაგრამ არ გათავისუფლებთ იგი. ჩვენ კომპილირება ერთად ჩადება და გაუშვით ქვეშ Valgrind, და ჩვენ ვხედავთ, რომ, მაშინ, როდესაც ჩვენ არ გვაქვს მეხსიერების შეცდომები, ჩვენ გვაქვს ერთი გაჟონვის. არსებობს 16 ბაიტი ნამდვილად წააგო, რაც იმას ნიშნავს, რომ მომცეთ, რომ მეხსიერების არ იყო ფარგლებს, როდესაც პროგრამის დასრულების. ახლა, Valgrind არ მოგვცეს ტონა ინფორმაციას გაჟონვის, მაგრამ თუ მივყვებით ამ პატარა შენიშვნა, რომ ეს იძლევა ქვემოთ მიმართ ბოლოში თავის ანგარიშს to გამეორება ერთად - გაჟონვის-შეამოწმოთ = სრული რომ ნახოთ სრულ დეტალებს გაჟონა მეხსიერება, ჩვენ კიდევ უფრო მეტი ინფორმაცია. ახლა კი, ბევრი რეზიუმე, Valgrind გვეუბნება, სადაც მეხსიერება, რომ დაიკარგა თავდაპირველად გამოყოფილი. ისე, როგორც ჩვენ ვიცით ეძებს წელს კოდებს, Valgrind გვამცნობს, რომ ჩვენ გაჟონა მეხსიერება გამოყოფილი ერთად ზარი malloc on line 8 leak.c ძირითად ფუნქციას. Pretty nifty. Valgrind სამი კატეგორია გაჟონვის გამოყენებით ამ თვალსაზრისით: აუცილებლად დაკარგა - ეს არის ბევრი გამოყოფილი მეხსიერება რომლის პროგრამა აღარ აქვს მაჩვენებელი. Valgrind იცის, რომ თქვენ ერთხელ ჰქონდა მაჩვენებელი მაგრამ მას შემდეგ დაკარგა სიმღერა იგი. ეს მეხსიერების აუცილებლად გაჟონა. არაპირდაპირ დაკარგა - ეს არის ბევრი გამოყოფილი მეხსიერება რომლის მხოლოდ მითითებას მას ასევე იკარგება. მაგალითად, თუ თქვენ დაგავიცყდათ თქვენი მომცეთ პირველი კვანძის of უკავშირდება სია, მაშინ პირველი კვანძის თავად იქნება აუცილებლად დაკარგა, ხოლო ნებისმიერი შემდგომი კვანძების იქნება არაპირდაპირ დაკარგა. შესაძლოა დაკარგა - ეს არის ბევრი გამოყოფილი მეხსიერება რომლის Valgrind არ შეიძლება იყოს დარწმუნებული არსებობს თუ არა მომცეთ თუ არა. ჯერ კიდევ მიუწვდომელია არის ბევრი გამოყოფილი მეხსიერება რომლის პროგრამა ჯერ კიდევ კურსორი ზე გასასვლელი, რომელიც, როგორც წესი, იმას ნიშნავს, რომ გლობალური ცვლადი რაოდენობა მას. შევამოწმოთ ეს ტბები, თქვენ ასევე უნდა შეიცავდეს ვარიანტი - ჯერ კიდევ მიუწვდომელია = დიახ თქვენს invocation of Valgrind. ამ სხვადასხვა შემთხვევებში შესაძლოა მოითხოვოს, სხვადასხვა სტრატეგიების დასუფთავების მათ, მაგრამ გაჟონვის უნდა აღმოიფხვრას. სამწუხაროდ, აფიქსირებს გაჟონვის შეიძლება იყოს ძნელი გასაკეთებელი, მას შემდეგ, რაც არასწორი მოუწოდებს თავისუფალი შეიძლება აფეთქება თქვენი პროგრამა. მაგალითად, თუ დავაკვირდებით invalid_free.c, ჩვენ ვხედავთ მაგალითს ცუდი მეხსიერება deallocation. რა უნდა იყოს ერთჯერადი ზარის გასათავისუფლებლად მთელი ბლოკი მეხსიერების მიუთითა მიერ int_block, სანაცვლოდ გახდეს მცდელობა გასათავისუფლებლად ყოველ GEO-ზომის სექციაში საქართველოს მეხსიერების ინდივიდუალურად. ეს ვერ კატასტროფულად. BooM! რა შეცდომა. ეს არის ნამდვილად არ არის კარგი. თუ თქვენ დავრჩებოდით ასეთი შეცდომა, თუმცა, და არ იცით სად უნდა გამოიყურებოდეს, დაეცემა უკან თქვენი ახალი საუკეთესო მეგობარი. თქვენ მიხვდა ეს - Valgrind. Valgrind, როგორც ყოველთვის, ზუსტად იცის, რა up. Alloc და თავისუფალი ითვლის არ ემთხვევა up. გვაქვს 1 alloc და 4 ათავისუფლებს. და Valgrind ასევე გვეუბნება თუ პირველი ცუდი უფასო ზარის - ერთი, რომ გამოიწვია blowup - მოდის - ხაზი 16. როგორც ხედავთ, ცუდი მოუწოდებს გასათავისუფლებლად მართლაც ცუდია, ამიტომ ჩვენ გირჩევთ გაქირავების თქვენი პროგრამის გაჟონვის ხოლო თქვენ მუშაობა მიღების ფუნქციონალური სწორი. დაწყება ეძებს გაჟონვის მხოლოდ მას შემდეგ თქვენი პროგრამა მუშაობს გამართულად, ყოველგვარი სხვა შეცდომები. და ეს ყველაფერი გვაქვს for this video. ახლა რას ელოდება? გადავიდეთ აწარმოებს Valgrind თქვენს პროგრამებს ახლავე. ჩემი სახელი არის Nate Hardison. ეს არის CS50. [CS50.TV]