[Powered by Google Translate] [Валгринд] [Нејт Хардисон, Универзитет Харвард] Ово је ЦС50, ЦС50.ТВ] Неке од најтежих грешака у Ц програмима долазе из лошег управљања меморијом. Постоји велики број начина да сјебемо ствари, укључујући доделу погрешну количину меморије, заборављајући да се покрене променљиве писања пре или после краја бафера, и ослобађање држати меморијске више пута. Симптоми варирају од повремених падова да мистериозно преписани вредности, често на местима и временима далеко од оригиналног грешке. Трасирање посматрану проблем назад на основни узрок корена може бити изазов, али срећом постоји програм који се зове корисна Валгринд који може да уради много да помогне. Покренете програм под Валгринд ће омогућити обимна провера издвајања гомилу меморије и приступа. Када Валгринд детектује проблем, то вам даје непосредан, директних информација која вам омогућава да лакше пронашли и решили проблем. Валгринд такође извештаје о мање смртоносна меморијских питањима, као што су меморијске цурења, распоређивању гомили меморије, и заборављање да га ослободе. Као наш компајлера, кланг, у нашој дебуггер, гдб, Валгринд је слободан софтвер, и то је инсталиран на уређају. Валгринд ради на свом бинарном извршне, није ваш ц или х изворни код.., па будите сигурни да сте саставили до-то-дате копију програма коришћењем цланг или Маке. Затим, ради свој програм под Валгринд може бити тако једноставно као само префикс стандардну програмску команду речју валгринд, која покреће Валгринд и покреће програм унутар њега. Приликом покретања, Валгринд се нека сложена јиггеринг за конфигурисање извршну за меморијске провера, тако да може да потраје мало да устане и ради. Програм ће затим извршити нормално, било је много спорије, а када се заврши, Валгринд ће одштампати резиме својој меморији употребе. Ако све прође добро, то ће изгледати отприлике овако: У овом случају, / цлеан_програм. је пут до програма желим да бежим. И док овај не предузима никакве аргументе, ако јесте ја бих их само тактика на крају команде, као и обично. Чиста програм је само глупо мали програм сам креирао који додељује простор за блок Интс на гомили, ставити неке вредности унутар њих, и ослобађа цео блок. То је оно што снимате за, без грешака и без пукотина. Други важан показатељ је укупан број бајтова додељених. У зависности од програма, ако вам издвајања су у мегабајтима или више, вероватно радиш нешто погрешно. Да ли непотребно одлагање дупликате? Да ли користите гомилу за складиштење, када би било боље да се користи стек? Дакле, меморијске грешке могу бити заиста зао. Што више отоврена они проузрокују спектакуларне падове, али чак и тада још увек може бити тешко да одредимо шта је тачно довело до несреће. Више подмукло, програм са меморијском грешке и даље може саставити чисто и даље може да изгледа исправно раде јер сте успели да добијете среће већину времена. Након неколико успешних резултата "," само помислити да је судар је случајност рачунара, али рачунар није у реду. Покретање Валгринд може да вам помогне да нађем узрок видљивих меморијских грешака као и пронашли грешке које вребају чак и не знамо о томе. Сваки пут Валгринд детектује проблем, штампа информације о томе шта је то приметио. Свака ставка је прилично кратак - извор линија увредљивим наставе, у чему је проблем, и мало информација о меморији укључена - али често је довољно информација да скренем вашу пажњу на право место. Ево примера Валгринд ради на програму бугги да ли неважећи читају хеап меморије. Ми не видимо грешке или упозорења у компилацију. Ух-ох, грешка резиме каже да постоје две грешке - два неисправна читања величине 4 - бајта, тј. Оба лоше чита догодила у главном функцији инвалид_реад.ц, први на реду 16 а други на линији 19. Погледајмо кода. Изгледа као први позив да принтф покушава да прочита једну инт прошлост краја нашег меморије блока. Ако погледамо уназад на излазу Валгринд а, видимо да Валгринд рекао нам је управо то. Адреса покушавамо да чита почиње 0 бајтова прошлост краја блока величине 16 бајтова - четири 32-битне ИНТС да смо додељени. То је, адреса смо покушавали да читају почиње на самом крају нашег блока, баш као што смо видели у нашем лошем принтф позива. Сада, неважећи цитано можда не изгледа као да је велик посао, али ако користите те податке да контролише проток вашег програма - На пример, као део уколико изјава или петља - онда ствари могу ћутке иде лоше. Гледајте како могу покренути програм инвалид_реад и ништа необично дешава. Страшно, зар не? Сада, хајде да погледамо неке више врста грешака које могу да наилазе у свом коду, па ћемо видети како Валгринд их открије. Управо смо видели пример једног инвалид_реад, па сад хајде да проверимо једну инвалид_врите. Опет, нема грешке или упозорења у компилацију. Ок, Валгринд каже да постоје две грешке у овом програму - и инвалид_врите и инвалид_реад. Хајде да проверимо ову шифру. Изгледа као да имамо инстанцу класичног стрлен плус један буг. Код не маллоц додатни бајт простора за / 0 карактера, па кад ул примерак отишао да га напишем на ссубстрлен "цс50 стена!" писало је 1 бајт прошлост краја нашег блока. Тхе инвалид_реад долази када правимо наш позив принтф. Принтф завршава читањем неважећи меморију када се чита / 0 карактер као што изгледа на крају овог низа Е то је штампа. Али ништа од тога побегао Валгринд. Видимо да је ухваћен инвалид_врите као део ул копије на линији 11 у главни, а инвалид_реад део принтф. Роцк он, Валгринд. Опет, ово можда не изгледа као велика ствар. Можемо покренути овај програм изнова и ван Валгринд и не видим никакве симптоме грешке. Ипак, хајде да погледамо мало варијација то види како ствари могу добити заиста лоше. Дакле, готово, ми смо злоупотребљавају ствари више него само мало у овом коду. Ми само додељивање простора на гомилу за два жице дужина цс50 стена, овај пут, сећајући / 0 карактер. Али онда бацамо у супер-дугом низу у меморијски блок да С указује на. Какав ефекат ће то имати на меморијској блока који Т указује? Па, ако Т указује на меморију која је само поред С, долази тек након ње, онда бисмо писали у делу Т. Хајде да покренете овај код. Погледајте шта се догодило. Жице се налазе у нашим гомилу блокова оба изгледа да је одштампан правилно. Ништа изгледа погрешно уопште. Међутим, хајде да се вратимо у наш код и коментар из линије где смо копирали цс50 стене у другој меморијској блока, указао од стране Т. Сада, када смо покренули овај код нас треба видети само садржај првог меморијског блока одштампати. Вау, иако нисмо ул копија било знакова у другој хеап блока, један је указао на по Т, добијамо отисак напоље. Заиста, стринг смо пуњена у нашем првом блоку заузеле прво блок и у другом блоку, чинећи све изгледа нормално. Валгринд, међутим, каже нам истиниту причу. Ту смо. Сви они неважећи чита и пише. Погледајмо пример друге врсте грешке. Овде смо нешто прилично несрећни. Ми зграби простор за интег на гомили, и ми се покрене инт показивач - п - да укаже на том простору. Међутим, док је наша показивач иницијализован, подаци који указују да је то управо год ђубре је у том делу гомиле. Дакле, када смо учитати да податке у инт, ми смо технички, покрене, али ми то урадити са џанк подацима. Позив да се афирмишу, што је згодно за отклањање грешака макро дефинисан у пригодно назван тврде библиотеке, ће прекинути програм и ако је његово стање тест не успе. То јест, ако сам није 0. У зависности од тога шта је у хеап простору, истакао по п, Овај програм може да се понекад ради и не у другим временима. Ако то ради, само смо посрећило. Компајлер неће ухватити ову грешку, али Валгринд сигуран вољу. Ту видимо грешку која произилази из нашег коришћења тог јунк података. Када доделити гомили меморију али не деаллоцате или ослободити га, која се зове цури. За малу, краткотрајне програму који покреће и одмах излазе, цурења су прилично безопасни, али за пројекат већег обима и / или дуговечност, чак и мала цурења могу једињење у нешто велики. За ЦС50, ми очекујемо да брине ослобађање свих гомиле меморије коју додели, пошто желимо да градимо вештине да правилно рукује процесом ручног захтева Ц. Да бисте то урадили, ваш програм треба да има тачан један-на-један кореспонденција између маллоц и фрее позиве. Срећом, Валгринд може да вам помогне са меморијским цурења превише. Овде је цури програм под називом леак.ц да издвоји простора на гомили, пише на њега, али га не ослободи. Ми смо саставити га са Направите и покрените га под валгринд, и видимо да, иако немамо меморијске грешке, имамо једну пукотину. Постоји 16 бајтова дефинитивно изгубљено, што значи да се показивач тог сећања није био у обиму када је програм изашао. Сада, Валгринд не дају нам гомилу информација о цурења, али ако пратимо ову малу напомену да даје доле према дну свог извештаја да поново покрећете са - цури-цхецк = пуна да видите све детаље процурио меморије, ћемо добити више информација. Сада, у хеап резимеу, Валгринд нам каже где меморија која је изгубљена је првобитно додељена. Као што знамо из гледа у изворном коду, Валгринд нас обавештава да смо процуриле меморију издвојила са позивом на маллоц на линији 8 од леак.ц у главном функцији. Прилично диван. Валгринд категорише цурења помоћу ове услове: Дефинитивно изгубили - то је гомила издвојено меморија на којима се програм више нема показивач. Валгринд зна да сте некада имали показивач, али су пошто је изгубио траг о томе. Ова меморија је дефинитивно процурела. Индиректно изгубили - то је гомила издвојено меморија којима су само показивачи на њега такође су изгубљени. На пример, ако сте изгубили показивач на први чвор повезану листу, онда прво сама чвор би се дефинитивно изгубљено, док је било накнадне чворови ће бити индиректно изгубљена. Можда је изгубио - то је гомила издвојено меморија на које Валгринд не можемо бити сигурни да ли је показивач или не. Ипак доступна је гомила издвојено меморија на који програм и даље има показивач на излазу, што обично значи да глобална променљива указује на њега. Да бисте проверили ових цурења, такође ћете морати да укључите опцију - Још увек доступан = иес у призивањем Валгринд. Ови различити предмети могу захтевати различите стратегије за њихово чишћење, али цури треба елиминисати. Нажалост, фиксирање цурење може бити тешко да уради, Од погрешних позива на бесплатно да дигне свој програм. На пример, ако гледамо инвалид_фрее.ц, видимо пример лошег меморијског Деалокација. Шта би требало да буде један позив да ослободи цео блок меморије указао на које инт_блоцк, уместо тога постао покушај да се ослободи сваког инт величине одељак сећања појединачно. Ово ће катастрофално пропасти. Бум! Шта грешка. Ово дефинитивно није добро. Ако сте заглављени са овом врстом грешке, ипак, и не знате где да погледате, пада назад на нови најбољи пријатељ. Погодили сте - Валгринд. Валгринд, као и увек, тачно зна шта је горе. У аллоц и слободно тачке не подударају. Имамо 1 аллоц и 4 ослобађа. И Валгринд нам такође говори где први лоше бесплатан позив - онај који је покренуло Бловуп - долази од - линија 16. Као што видите, лоше позиви на слободне су заиста лоши, па препоручујемо да пустите да вам програм цурење док радите на томе функционалност исправна. Почетак у потрази за цурење тек након ваш програм ради исправно, без икаквих других грешака. И то је све што имамо за овај видео. Сада шта чекате? Иди покренути Валгринд на вашим програмима сада. Моје име је Нејт Хардисон. Ово је ЦС50. [ЦС50.ТВ]