[Powered by Google Translate] [Valgrind] [Нејт Hardison, Универзитетот Харвард] Ова е CS50, CS50.TV] Некои од најтешките грешки во C програми доаѓаат од запоставување на меморија. Постојат голем број на начини да завртка работите, вклучувајќи доделување на погрешен износ на меморија, заборавајќи да се иницијализира променливи, писмена форма пред или по завршувањето на тампон, и ослободување задржи мемориската повеќе пати. Симптомите варираат од наизменичното блокира да мистериозно препишани вредности, често на места и времиња далеку од оригиналниот грешка. По трагите на набљудуваните проблем назад на основната коренот може да биде предизвик, но за среќа има корисни програма наречена Valgrind дека може да направи многу за да им помогне. Ќе ја стартувате програмата под Valgrind за да се овозможи обемна проверка на грамада меморија алокации и пристапи. Кога Valgrind детектира проблем, тоа ви дава веднаш, директни информации што ви овозможува да повеќе лесно да најдете и да ја поправите проблемот. Valgrind исто така извештаи за помалку смртоносен меморија прашања, како меморија протекување, распределба на грамада меморија, и заборавање за да се ослободи. Се допаѓа нашиот компајлер, ѕвекот, во нашата дебагерот, GDB, Valgrind е слободен софтвер, и е инсталиран на уредот. Valgrind работи на вашиот бинарна извршна, не твојот. C или. ж изворниот код на датотеки, па бидете сигурни дека имате подготвено up-to-date копија на вашата програма користење ѕвекот или создавам. Потоа, трчање вашата програма под Valgrind може да биде едноставно како само prefixing на стандардна програма командата со зборот Valgrind, која ќе почне со Valgrind и работи на програмата во него. При стартување, Valgrind прави некои сложени jiggering да одбереш извршна за меморија проверки, па тоа може да потрае малку да се нагоре и трчање. Програмата тогаш ќе се извршува нормално, тоа да биде многу побавно, и кога ќе заврши, Valgrind ќе печати резиме на употребата на меморијата. Ако се оди добро, тоа ќе изгледа нешто како ова: Во овој случај,. / Clean_program е патот до програмата Сакам да се кандидира. И додека ова не се преземат какви било аргументи, ако тоа го правеше Би само да ги тактика за да на крајот на командната како и обично. Чиста програмата е само глупо малку програма Јас создаде што издвојува простор за блок од ints на грамада, стави некои вредности во внатрешноста на нив, и ослободува целиот блок. Ова е она што се снима за, без грешки и без протекување. Друга важна метрички е вкупниот број на бајти распределени. Зависно од програмата, ако вашиот средства се во мегабајти или повисоко, ти си веројатно се прават нешто погрешно. Дали сте непотребно чување на дупликати? Дали сте користење на грамада за складирање, кога тоа ќе биде подобро да се користи магацинот? Значи, меморија грешки може да биде навистина зло. Повеќе отворена оние предизвика спектакуларни несреќи, но дури и тогаш тоа сепак може да биде тешко да ги лоцирам што точно довело до несреќата. Повеќе подмолно, програма со меморија грешка уште може да собере чисто и уште може да изгледа да се работи правилно затоа што успеа да добиете среќа поголемиот дел од времето. По неколку "успешни резултати" вие само може да мислат дека несреќата е среќа на компјутер, но компјутерот не е во ред. Вклучување Valgrind може да ви помогне да ги пратите одредување на причината на видливи меморија грешки како и да најдете демнат грешки дури не сеуште знаат. Секој пат Valgrind детектира проблем, тоа отпечатоци информации за она што го почитуваат. Секоја ставка е прилично изразителен - изворот линија на навреда настава, што на ова прашање е, и малку информации за меморијата вклучени - но често тоа е доволно информации да се насочи вниманието на вистинското место. Еве еден пример на Valgrind работи на кабриолет програма што го прави невалиден читање на грамада меморија. Ние не гледам грешки или предупредувања во компилација. Ух-Ох, грешка резиме вели дека постојат две грешки - две неважечки прочитано на големина 4 - бајти, тоа е. Двете лоши чита случи во главната функција на invalid_read.c, прв на линија 16, а втората on-line 19. Ајде да погледнеме во кодот. Изгледа како првиот повик на printf обидува да прочитате една int минатото крајот на нашата меморија блок. Ако ги погледнеме назад во производството Valgrind е, можеме да видиме дека Valgrind ни кажа токму тоа. Адреса ние се обидуваме да го прочитате почнува 0 бајти минатото на крајот на блокот на големина 16 бајти - четири 32-битен ints дека ние распределени. Што е, на адресата што се обидуваат да го прочитате започнува токму на крајот од наше маало, само како што гледаме во нашите лоши printf повик. Сега, неважечки прочитано не може да изгледа како толку голем договор, но ако сте со користење на податоците да се контролира протокот на вашата програма - на пример, како дел од, ако изјавата или јамка - тогаш работите тивко може да оди лошо. Види како можам да се кандидира на invalid_read програма и ништо од обичните случува. Страшно, нели? Сега, ајде да погледнеме некои повеќе видови на грешки кои може да се судрите во вашиот код, и ќе видиме како Valgrind ги детектира. Ние само видов пример за invalid_read, Па сега ајде да се провери од една invalid_write. Повторно, нема грешки или предупредувања во компилација. Океј, Valgrind вели дека постојат две грешки во оваа програма - и invalid_write и invalid_read. Ајде проверете го овој код. Изгледа имаме пример на класичен strlen плус една бубачка. Кодексот не Примерок екстра бајт на просторот за / 0 карактер, па кога ул копија отиде да го пишувам на ssubstrlen "cs50 камења!" го напишал 1 бајт минатото на крајот од наше маало. На invalid_read доаѓа кога ќе го направи нашиот повик да printf. Printf завршува до читање неправилен меморија кога станува чита / 0 карактер како што изгледа на крајот на овој Е стринг е печатење. Но ништо од тоа избегна Valgrind. Гледаме дека фатени на invalid_write како дел од ул копија на линија 11 од главната и invalid_read е дел од printf. Рок на, Valgrind. Повторно, ова не може да изгледа како голема работа. Ние може да ја извршите оваа програма одново и надвор од Valgrind и не гледам никаква грешка симптоми. Сепак, ајде да погледнеме мала варијација на овој за да ја видите како работите може да се добие навистина лошо. Па, готово, ние се злоупотребува работи повеќе од само малку во овој код. Ние сме само распределба на простор на грамада за две низи должината на cs50 карпи, овој пат, сеќавајќи се на / 0 карактер. Но, тогаш ние фрли во супер-долга низа во меморискиот блок што S е да се покажува. Каков ефект ќе кои имаат за мемориски блок дека Т поени? Па, ако Т укажува на меморија, која е само непосредна близина до С, доаѓа веднаш по него, тогаш ние би можеле да го имаат напишано над дел од Т Да ја извршите оваа код. Погледнете што се случи. Жиците се чуваат во нашата грамада блокови и се појави да се испечати правилно. Ништо не чини погрешно на сите. Сепак, да се вратиме во нашиот код и Коментар од линијата каде што копирате cs50 карпи во втората мемориски блок, посочи од т. Сега, кога ние ја извршите оваа код ние треба да само ја видите содржината на првиот мемориски блок испечатите. Леле, иако ние не ул копија никакви знаци во втората грамада блок, еден укажа на T, добиеме испечатите. Всушност, низа ние полнети во нашата првиот блок зазедоа првиот блок и во вториот блок, што се чини нормално. Valgrind, сепак, ни кажува вистинската приказна. Таму ќе одиме. Сите оние неважечки чита и пишува. Ајде да погледнеме еден пример на друг вид на грешка. Еве ние се направи нешто, а жално. Ние го дофати простор за int на грамада, и ние се иницијализира на int покажувачот - P - да се укаже на тој простор. Сепак, додека нашите покажувачот е иницијализиран, податоците што тоа е што укажува на само има она што ѓубре е во тој дел на грамада. Значи, кога ќе се вчита податоците во int i, ние технички јас се иницијализира, но тоа го правиме со сметот на податоци. Повикот да тврдат, која е корисна за дебагирање макро дефинирани во потполност наречен тврдат библиотека, ќе ја прекине програмата, доколку нејзините тест состојба не успее. Тоа е, ако не е 0. Во зависност од она што беше во грамада просторот, посочи со p, оваа програма би можеле да работат понекогаш и не успеваат во други времиња. Ако тоа функционира, ние сме само добива среќа. На компајлерот не ќе се фати оваа грешка, но Valgrind сигурни волја. Има гледаме грешка произлегуваат од нашата употреба на тоа ѓубре податоци. Кога ќе одвои грамада меморија, но не го deallocate или ослободи неа, што се нарекува протекуваат. За мала, краткотрајна програма која работи и веднаш излегува, протекување се прилично безопасен, но за проект од поголема големина и / или долговечноста, дури и мал истекување може да соединение во нешто поголеми. За CS50, ние не очекуваме да се грижи за ослободување на сите на грамада меморија, која ви доделат, Бидејќи ние сакаме да се изгради вештини за правилно да се справи со рачен процес бара од страна на В Да го стори тоа, вашата програма треба да имаат точно еден-на-еден преписка помеѓу Примерок и бесплатни разговори. За среќа, Valgrind може да ви помогне со меморија протекување премногу. Тука е спукан програма наречена leak.c дека доделува простор на грамада, пишува за тоа, но не го ослободи. Ние го компајлирате со создавам и да ја стартувате под Valgrind, и гледаме дека, додека ние немаме меморија грешки, ние имаме една протекуваат. Постојат 16 бајти дефинитивно изгубени, што значи дека го покажувачот во тој меморијата не е во опсегот кога на програмата постоеле. Сега, Valgrind не ни даде еден тон на информации за течење, но ако ние ја следиме оваа мала забелешка дека тоа му дава надолу кон дното на извештајот на повторување со - протекуваат-проверка = целосна да ја видите комплетната детали протекоа меморија, ќе добиете повеќе информации. Сега, во грамада резиме, Valgrind ни кажува каде меморија, која е изгубена првично беше распределени. Исто како што знаеме од гледање во изворниот код, Valgrind нè информира дека протекоа на меморијата доделени со повик до Примерок на алинеја 8 од leak.c во главната функција. Убави Вешта. Valgrind категоризира протекување користење на овие термини: Сигурно е изгубен - ова е грамада распределени меморија кој на програмата веќе нема покажувач. Valgrind знае дека некогаш имал покажувачот но оттогаш се губеше од неа. Оваа меморија е дефинитивно протекоа. Индиректно изгубени - ова е грамада распределени меморија кој само совети како да се, исто така, се губат. На пример, ако сте ја изгубиле вашиот покажувач на првиот јазол на поврзани листа, тогаш првиот јазол себе ќе биде дефинитивно изгубени, додека сите последователни јазли ќе бидат индиректно изгубени. Можно е изгубена - ова е грамада распределуваат меморија кој Valgrind не може да биде сигурен дали постои покажувач или не. Сепак достапно е грамада распределени меморија кои на програмата се уште има покажувач на излез, кои обично значи дека глобалната променлива поени за тоа. Да се ​​провери за овие протекување, исто така, ќе мора да вклучува опција - Сеуште достапно = да во вашиот повикување на Valgrind. Овие различни случаи може да бараат различни стратегии за чистење на нив, но протекување треба да се отстранат. За жал, одредување протекување може да биде тешко да се направи, бидејќи неточни повици за бесплатно да ја кренат својата програма. На пример, ако гледаме invalid_free.c, можеме да видиме еден пример за лоша меморија deallocation. Што треба да биде еден повик за ослободување на целиот блок меморија посочи од int_block, има наместо да стане обид да се ослободи секој int големина дел на меморијата поединечно. Ова нема да успее катастрофално. Бум! Што грешка. Ова дефинитивно не е добар. Ако сте заглавени со овој вид на грешка, иако, и вие не знаете каде да се погледне, се врати на вашиот нов најдобар пријател. Ќе го претпоставам - Valgrind. Valgrind, како и секогаш, точно знае што е горе. На alloc и слободни точки не се совпаѓаат. Имаме 1 alloc и 4 ослободува. И Valgrind исто така ни кажува каде што првиот лошо бесплатен повик - оној кој предизвика скандал - доаѓа од - линија 16. Како што гледате, лоши повици за ослободување се навистина лоши, па ви препорачуваме овозможи вашата програма течење додека си работат на добивање на функционалноста точни. Почнете да барате протекување само по вашата програма е работи правилно, без какви било други грешки. И тоа е се што имам за ова видео. Сега што чекаш? Оди кандидира Valgrind на вашите програми во моментов. Моето име е Нејт Hardison. Ова е CS50. [CS50.TV]