[Powered by Google Translate] [Shprehje]
[Nate Hardison, Universiteti i Harvardit]
Kjo është CS50, CS50.TV]
Disa nga mete më të vështira në programet C
vijnë nga keqadministrimi i kujtesës.
Ka një numër të madh të mënyrave për të vidhos gjërat,
përfshirë alokimin sasinë e gabuar e kujtesës,
harruar të nisja variablave,
shkruar para ose pas përfundimit të një tampon,
dhe liruar mbajtur herë kujtesës shumta.
Simptomat variojnë nga crashes përhershme
të vlerave misterioze overwritten,
shpesh në vende dhe kohë larg nga gabimi origjinal.
Tracing problemin vërejtur përsëri shkaku themelor rrënjë
mund të jenë të vështira,
por fatmirësisht ka një program të dobishme të quajtur Shprehje
që mund të bëjë shumë për të ndihmuar.
>> Ju drejtuar një program nën Shprehje për të mundësuar
Kontrollimi i gjerë i alokimeve kujtesës tog dhe akseseve.
Kur Shprehje zbulon një problem, kjo ju jep menjëhershme,
Informacioni i drejtpërdrejtë që ju lejon të
më të lehtë të gjeni dhe të zgjidhur problemin.
Shprehje edhe raporte mbi çështje të kujtesës më pak vdekjeprurëse,
të tilla si rrjedhjet e kujtesës, e kujtesës tog ndarjes,
dhe duke harruar për të liruar atë.
Ashtu si tingëllimë tonë, përpilues, në Rregullues tonë, GDB,
Shprehje është software i lirë, dhe kjo është instaluar në aplikim.
Shprehje shkon në ekzekutues tuaj binar,
jo. tuaj ose c. kodin burim h fotografi,
në mënyrë të sigurt që ju keni hartuar një kopje të up-to-date të programit tuaj
përdorur ose tingëllimë të bërë.
Pastaj, drejtimin e programit tuaj nën Shprehje mund të jetë
aq e thjeshtë sa vetëm prefixing komandën standarde programin Shprehje me fjalë,
e cila fillon Shprehje dhe drejton programin në brendësi të saj.
Kur fillon, Shprehje bën disa komplekse
jiggering për konfigurimin e ekzekutueshme për kontrollet e kujtesës,
kështu që ajo mund të marrë një grimë për të marrë dhe drejtimin.
Programi do të ekzekutojë normalisht, të jetë ajo shumë më ngadalë,
dhe kur ajo mbaron, Shprehje do të shtypura një përmbledhje të përdorimit të saj kujtesës.
Nëse gjithçka shkon mirë, kjo do të duket diçka si kjo:
Në këtë rast,. / Clean_program
është rruga për programin dua për të kandiduar.
Dhe, ndërsa kjo nuk ka marrë ndonjë argumente,
në qoftë se ai e bëri Dua vetëm ato në litar në fund të komandës si zakonisht.
Programi pastër është vetëm një program silly pak kam krijuar
që ndan hapësirë ​​për një bllok të ints në tog,
vënë disa vlera në brendësi të tyre, dhe liron bllok të tërë.
Kjo është ajo që ju jeni të shtënat për të, pa gabime dhe pa rrjedhjet.
>> Një tjetër metrikë e rëndësishme është numri i përgjithshëm i bytes alokuara.
Në varësi të programit, nëse tuaja janë alokimet në MB ose më të larta,
ndoshta ju jeni duke bërë diçka të gabuar.
A jeni të panevojshme ruajtjen kopje identike?
A jeni duke përdorur tog për ruajtjen, kur ajo do të jetë më mirë për të përdorur rafte?
Pra, gabimet e kujtesës mund të jetë me të vërtetë e keqe.
Ato më të dukshme të shkaktojë crashes spektakolare,
por edhe atëherë ajo ende mund të jetë e vështirë për të identifikuar
çfarë saktësisht çoi në rrëzimin.
Më shumë insidiously, një program me një gabim e kujtesës
ende mund të përpilojnë pastër
dhe ende mund të duket për të punuar si duhet
sepse keni arritur të merrni me fat më të madhe të kohës.
Pas disa rezultateve të suksesshme ","
ju vetëm mund të mendojnë se një përplasje është një pikë për shans i kompjuterit,
por kompjuteri nuk është e gabuar.
>> Drejtimin Shprehje mund të ju ndihmojë të gjetur shkakun e gabimeve të dukshme të kujtesës
si dhe të gjeni përgjojnë gabimet ju nuk dini ende rreth.
Çdo herë Shprehje zbulon një problem, ajo printon informacion në lidhje me atë vërejtur.
Çdo artikull është mjaft i shkurtër -
vija burimi i udhëzimit ofendim, çfarë është çështja,
dhe një info pak për kujtesën e përfshirë -
por shpesh kjo është informacion të mjaftueshëm për të drejtuar vëmendjen tuaj në vendin e duhur.
Këtu është një shembull i Shprehje kandidon për një program buggy
që bën një lexuar pavlefshme e kujtesës tog.
Ne e shohim asnjë gabim ose paralajmërime në hartimin.
Uh-oh, përmbledhje gabimi thotë se ka dy gabime -
dy herë lexuar pavlefshme të madhësisë 4 - bytes, që është.
Dy keqe lexon ndodhur në funksion kryesor të invalid_read.c,
i pari on line 16 dhe të dytë në linjë 19.
Le të shikojmë në kodin.
Duket si thirrje për të parë printf përpiqet për të lexuar një int kaluara në fund të bllokut tonë të kujtesës.
Nëse ne shikojmë prapa në dalje Shprehje së,
ne shohim se Shprehje na tha pikërisht këtë.
Adresa ne jemi duke u përpjekur për të lexuar fillon 0 bytes
kaluara në fund të bllokut të madhësisë 16 bytes -
katër 32-bit ints që ne alokuara.
Kjo është, adresa ne ishin duke u përpjekur për të lexuar fillon të drejtën në fund të bllokut tonë,
ashtu si ne e shohim në thirrjen tonë printf keqe.
Tani, të pavlefshme lexuar mund të mos duket si kjo e madhe e një marrëveshje,
por në qoftë se ju jeni duke përdorur që të dhënat për të kontrolluar rrjedhën e programit tuaj -
për shembull, si pjesë e një në qoftë se deklarata ose loop -
atëherë gjërat mund të shkojnë keq në heshtje.
Shikojnë se si unë mund të drejtuar programin invalid_read
dhe asgjë nga të zakonshëm ndodh.
Frikshme, Huh?
>> Tani, le të shohim në disa lloje më të gabimeve që ju mund të hasni në kodin tuaj,
dhe ne do të shohim se si Shprehje e zbulon ato.
Ne vetëm e pa një shembull të një invalid_read,
kështu që tani le të shikoni një invalid_write.
Përsëri, nuk ka gabime apo paralajmërimet në hartimin.
Mirë, Shprehje thotë se ka dy gabime në këtë program -
dhe invalid_write dhe një invalid_read.
Le të kontrolluar këtë kod.
Duket sikur ne kemi marrë një shembull të strlen klasik plus një bug.
Kodi nuk malloc një bajt shtesë të hapësirës
për të karakter / 0,
kështu që kur str kopje shkoi për të shkruar atë në ssubstrlen "CS50 shkëmbinjve!"
ajo shkroi 1 bajt kaluara në fund të bllokut tonë.
The invalid_read vjen kur kemi bërë thirrjen tonë për printf.
Printf përfundon leximin e kujtesës pavlefshëm kur ai lexon / 0 karakter
si duket në fund të këtij vargut E kjo është shtypje.
Por kjo nuk shpëtoi Shprehje.
Ne e shohim se ajo kapur invalid_write si pjesë e kopjes rr
në përputhje 11 e kryesor, dhe invalid_read është pjesë e printf.
Rock në, Shprehje.
Përsëri, kjo nuk mund të duket si një marrëveshje e madhe.
Ne mund të drejtuar këtë program pa pushim jashtë Shprehje
dhe nuk shoh asnjë simptome gabim.
>> Megjithatë, le të shohim në një variacion të vogël të kësaj për të parë
se si gjërat mund të merrni të vërtetë e keqe.
Pra, jepet, ne po abuzojnë gjëra më shumë se vetëm një grimë në këtë kod.
Ne jemi vetëm shpërndarjen hapësirë ​​në grumbull për dy vargjet
gjatësia e CS50 shkëmbinjve,
këtë herë, kujtohet / 0 karakter.
Por pastaj ne e hedhin në një varg të super-të gjatë në bllokun e kujtesës
se S është duke treguar për të.
Çfarë efekti do të ketë kjo në bllok kujtesës që pikë në T?
E pra, nëse pikë t për të kujtesës që është vetëm ngjitur me S,
vjen vetëm pas saj,
atëherë ne mund të ketë shkruar mbi pjesë të T.
Le të drejtuar këtë kod.
Shikoni se çfarë ka ndodhur.
Vargjet ne ruajtura në blloqet tona grumbullosh të dyja duket se kanë shtypur saktë.
Asgjë nuk duket e gabuar në të gjitha.
Sidoqoftë, le të kthehemi në kodin tonë dhe
komentuar nga linjën ku ne kopje CS50 shkëmbinj
në bllokun e dytë e kujtesës, vuri në dukje nga t.
Tani, kur ne të drejtuar këtë kod ne duhet
vetëm shikoni përmbajtjen e bllokut të parë të shtypura jashtë kujtesës.
Whoa, edhe pse ne nuk str kopje
ndonjë karaktere në bllokun e dytë grumbull, ai vuri në dukje nga T,
ne kemi marrë një të shtypura jashtë.
Në të vërtetë, ne string mbushur në bllokun tonë të parë
morën bllokun e parë dhe në bllokun e dytë,
bërë gjithçka duket normale.
Shprehje, edhe pse, na tregon historinë e vërtetë.
Nuk shkojmë.
Të gjithë ata pavlefshme lexon dhe shkruan.
>> Le të shikojmë në një shembull të një tjetër lloj të gabimit.
Këtu kemi të bëjmë diçka më tepër fatkeq.
Ne rrëmbyer hapësirë ​​për një int mbi tok,
dhe ne nisja një tregues int - p - për pikë në atë hapësirë.
Megjithatë, ndërsa treguesin jonë është initialized,
të dhënat që ai është treguar të vetëm ka çfarëdo junk është në atë pjesë të tog.
Pra, kur ne load që të dhënat në int i,
ne teknikisht nisja i,
por ne bëjmë kështu me të dhëna junk.
Thirrja tek pohojnë, e cila është një makro dobishëm Debugging
përcaktuar në bibliotekë quajtur me vend pohojnë,
do të ndërpresin shtatzëninë programi nëse gjendja e tij testi dështon.
Kjo është, në qoftë se unë nuk është 0.
Varësisht se çfarë ishte në hapësirë ​​tog me ta, vuri në dukje nga p,
ky program mund të punojnë dhe nganjëherë dështojnë në raste të tjera.
Në qoftë se ajo punon, ne jemi vetëm duke u fat.
Përpiluesit nuk do të arrijë këtë gabim, por Shprehje do të sigurt.
Nuk shohim gabimin që rrjedh nga përdorimi tonë të të dhënave që junk.
>> Kur ju siguroj kujtesë tog por mos mos rezervim apo liruar atë,
që quhet një rrjedhje.
Për një program të vogël, jetëshkurtër që shkon dhe menjëherë daljet,
rrjedhjet janë mjaft të padëmshme,
por për një projekt të përmasave të mëdha dhe / ose jetëgjatësinë,
edhe një rrjedhje të vogël mund të përbëjë në diçka të madhe.
Për CS50, ne nuk presin që ju të
të kujdeset për të liruar të gjithë kujtesën grumbull që ju shpërndarë,
pasi ne duam që ju të ndërtuar aftësitë për të trajtuar si duhet procesin manual
kërkohet nga C.
Për ta bërë këtë, programi juaj duhet të ketë një saktë
një-për-një korrespondencë mes malloc dhe thirrje falas.
Për fat të mirë, Shprehje mund të ju ndihmojë me rrjedhjet e kujtesës shumë.
Këtu është një program i quajtur pikon leak.c që ndan
hapësirë ​​në tog, shkruan në të, por nuk lirojë atë.
Ne hartimin atë me të bërë dhe drejtuar atë nën Shprehje,
dhe ne shohim se, ndërsa ne nuk kemi gabime kujtesës,
ne nuk kemi një rrjedhje.
Nuk janë 16 bytes humbur përfundimisht,
thotë se tregues për atë memorie nuk ishte në fushën kur programi exited.
Tani, Shprehje nuk na jep një ton të informacionit në lidhje me rrjedhje,
por në qoftë se ne ndjekim këtë shënim të vogël se ajo i jep poshtë drejt fund të raportit të tij
për ribërjen me - rrjedhje-check = plotë
për të parë detajet e plota të kujtesës rrjedhur,
ne do të merrni më shumë informacion.
Tani, në përmbledhje tog,
Shprehje e na tregon ku kujtesës që është humbur është ndarë fillimisht.
Ashtu siç e dimë nga kërkoj në kodin burim,
Shprehje na informon se ne rrjedhur kujtesës
ndarë me një thirrje për malloc on line 8 të leak.c
në funksion kryesor.
Pretty mrekullueshëm.
>> Shprehje e kategorizon rrjedhjet përdorur këto terma:
Humbur definitivisht - kjo është kujtesa tog alokuar
në të cilat programi nuk ka një tregues.
Shprehje e di që ju dikur e kishte treguesin, por që kanë humbur gjurmët e saj.
Kjo memorie është zbuluar përfundimisht.
Humbur në mënyrë të tërthortë - kjo është kujtesa tog alokuar
në të cilën pointers vetëm për atë edhe janë të humbur.
Për shembull, nëse keni humbur treguesin tuaj të nyjen e parë të një liste të lidhura,
pastaj nyjen e parë vetë do të humbasin përfundimisht,
ndërsa çdo nyje pasuese do të jetë e humbur në mënyrë të tërthortë.
Humbur ndoshta - kjo është kujtesa tog alokuar
tek e cila Shprehje nuk mund të jetë i sigurte nëse ka një akrep ose jo.
Ende e arritshme është e kujtesës tog alokuar
në të cilën programi ende ka një tregues në dalje,
që zakonisht do të thotë se një pikë globale ndryshueshme të saj.
Për të kontrolluar për këto rrjedhjet, ju do të duhet të përfshijë opsionin
- Ende të arritshme = yes
në thirrje tuaj të Shprehje.
>> Këto raste të ndryshme mund të kërkojnë strategji të ndryshme për pastrimin e tyre lart,
por rrjedhjet duhet të eliminohen.
Fatkeqësisht, fiksimin rrjedhjet mund të jetë e vështirë për të bërë,
pasi thirrjet pasakta të lirë mund të hedhur në erë programin tuaj.
Për shembull, nëse ne shikojmë në invalid_free.c,
ne shohim një shembull të keq deallocation kujtesës.
Çfarë duhet të jetë një thirrje e vetme për të liruar e bllokut të gjithë
e kujtesës vuri në dukje nga int_block,
në vend është bërë një përpjekje për të liruar çdo seksion int-sized
i memories individualisht.
Kjo do të dështojnë katastrofike.
Boom! Çfarë një gabim.
Kjo nuk është aspak e mirë.
Nëse jeni të mbërthyer me këtë lloj të gabimit, edhe pse, dhe ju nuk e dini ku të kërkoni,
bien përsëri në mik të ri tuaj më të mirë.
Ju mendoi ai - Shprehje.
Shprehje, si gjithmonë, e di saktësisht se çfarë është lart.
Numëron shenjat e lirë dhe nuk përputhen deri.
Ne kemi marrë shenjat e 1 dhe 4 çliron.
Dhe Shprehje gjithashtu na tregon se ku thirrja e parë e keqe lirë -
ai që shkaktoi grindje - po vjen nga -
Shkarko 16.
Siç e shihni, e quan të këqija të lirë janë me të vërtetë e keqe,
kështu që ne rekomandojmë lënë rrjedhje tuaj program
ndërsa ju jeni duke punuar në marrjen funksionalitetin e saktë.
Të fillojmë të shikojmë për rrjedhjet vetëm pasi programi juaj është duke punuar si duhet,
pa gabime të tjera.
>> Dhe kjo është e gjitha ne kemi marrë për këtë video.
Tani çfarë jeni duke pritur për të?
Go drejtuar Shprehje në programet tuaja të drejtë tani.
Emri im është Nate Hardison. Kjo është CS50. [CS50.TV]