ce să fac cu un defect de segmentare 11
Din anumite motive, am decis să construiesc un produs folosind C. Dacă obiectivul a fost eficiența codului, a fost un dezastru. Dar, ca instrument de creștere personală, cred că am învățat mult mai multe despre programare în acest proces.
de exemplu, acum știu mai precis de ce un dicționar python și o listă se comportă diferit și ce înseamnă cu adevărat să „treci prin referință.”
cu toate acestea, dacă ar exista o barieră care să mă facă să nu vreau niciodată să mă întorc la C, ar fi temutul” defect de segmentare 11″, urmat îndeaproape de ” Abort Trap 6.”
aceste două erori apar în timpul rulării, ceea ce le face dificil de depanat. Xcode, Eclipse sau alte instrumente de depanare sunt foarte utile, dar am învățat că este mult mai important să învățăm care sunt aceste lucruri și să venim cu proceduri pentru a aborda procesul de depanare. Acestea sunt doar notele mele despre propriile mele greșeli comune. Sper să fac din aceasta o listă de depanare pentru oricine are propriile probleme. Vreau să acopere cel puțin problemele mele stupide, astfel încât să vă puteți concentra pe probleme reale de codificare.
o eroare de segmentare înseamnă că programul dvs. a încercat să acceseze ceva ce nu trebuia. Asta e o parte a problemei. Există multe motive pentru care un program poate accesa lucruri pe care nu ar trebui să le facă, dar codul compilat spune destul de mult „#$#@^*&!”în schimb. Dacă te gândești la asta, nu ai vrea să trebuiască să explici cuiva de ce te bagă într-un loc sensibil te înnebunește. Vrei doar să nu mai facă asta. Din fericire, computerele sunt atât proaste, cât și surprinzător de răbdătoare după aproximativ 75 de ani de inginerie. Vor continua să trimită defecte Seg, dar (de obicei) nu vor înceta să fie prieteni după ce se întâmplă a 1000-a oară.
ce este capcana de avort?
nu este atât de diferit. Undeva, computerul tău și-a spus să întrerupă programul. Din nou, nu foarte util. Cu toate acestea, apare de obicei atunci când încercați să faceți ceva de genul acces string
a unui șir cu două caractere "nw"
sau nu reușiți să alocați suficientă memorie char string
pentru un șir sau matrice precum "way"
.
ce ar trebui să faci cu un defect Seg?
tutorialele pe care le citesc tind să se concentreze pe utilizarea instrumentelor de depanare precum lldb, gdb și așa mai departe. Asta e tot bine și dandy. Da, ar trebui să rulați gcc -g
mai întâi și apoi lldb executable_name
și apoi run -flag1 -flag2
pentru a vedea dacă vă ajută să vă dați seama. Dar, uneori, nu există nici un fel de ajutor. Am o listă de lucruri pentru a verifica, deși.
- verificați dacă variabilele globale ale programului dvs. necesare au valori. Acest lucru sa întâmplat mai ales pentru că am creat steaguri care au completat o grămadă de valori care trebuiau stabilite înainte de a rula. Cu toate acestea, ce se întâmplă dacă nu pun nimic? Seg Vina 11! Au existat un număr de ori am *crezut* vars au fost stabilite atunci când acestea nu au fost și care a făcut pentru bug-uri provocatoare. Mai bine, încercați să păstrați globalele la o limită, astfel încât acestea să fie mai ușor de urmărit.
- malloc este atât prietenul tău, cât și dușmanul tău. Mai ales cu intrări de utilizator, poate fi foarte dificil de a aloca memorie și apoi copiați, concateneze și de a face orice altceva pe drum. Cunoașteți bine această comandă și cum funcționează. Și nu uitați să
free()
memoria când ați terminat! - utilizați
char var
pentru a determina dimensiunea unui caracter* pentru alocarea memoriei. Cea mai mare parte a problemei am implicat atribuirea variabilelor pentru a accepta în cele din urmă un șir. Am văzut alte sfaturi, dar dacă este un șir cu care lucrați, cred că a foststrlen()
a funcționat cel mai consecvent. Aveți nevoie de +1 pentru\0
(null) pentru a termina șirul la sfârșit. - utilizați
int arr) +1)]
pentru matrice de alte tipuri. Este un mod ciudat de a face lucrurile, dar asta obții cu un limbaj de nivel scăzut. -
\0
reprezintă null și va termina o matrice. Poate fi util atunci când încercați să preveniți problemele de depășire a tamponului. - încercați să utilizați constante definite cât mai mult posibil. Ori de câte ori sunt în măsură să definească lucrurile la precompile, se va economisi timp de depanare mai târziu.
- înțelegeți pentru ce sunt fișierele antet. Multe dintre tutoriale vă vor spune ce conține un fișier antet, dar nu este întotdeauna clar pentru ce sunt. Fișierele antet sunt capturate la timp de pre-compilare și să ofere un rezumat al variabilelor și funcțiile disponibile pentru programul *înainte de a compilează*. Acest lucru înseamnă că .fișierele c incluse în program vor putea accesa aceste funcții, cu condiția ca
#include <headerfile.h>
să fie adăugat la fișier. O convenție bună este de a crea un .h fișier ori de câte ori creați un .C, și includeți-l în c. - cele mai multe pentru bucle merg astfel:
for (int i=0; i < stop; i++)
o modalitate ușoară de a avea o capcană de avort este de a pune un hectar în fațastop
. - păstrați problemele conținute. Încercați să faceți astfel încât fiecare fișier să facă câteva lucruri discrete și nimic altceva. Dacă aveți pentru a vâna prin diferite fișiere peste și despre, Se poate face găsirea problemele de vina seg foarte dificil.
- matematica de calculator este greu. Nu este chiar, dar lucrurile mici provoacă mari probleme.
char variable
de exemplu, înseamnă o matrice care conține două elemente, dar pentru că indexurile încep de la 0, asta înseamnă că puteți merge doar până la numărul 1. - șiruri de format de imprimare ca tipul potrivit. Din fericire, acest lucru este de obicei prins la momentul compilării, dar poate provoca în continuare probleme. Asigurați-vă că caracterul format
%{whatever}
se potrivește cu orice variabilă doriți să o introduceți.
asta e tot ce am pentru moment. Sper că nenorocirile mele v-au salvat niște dureri de cap pe drum! Dacă toate celelalte nu reușesc, acum am o listă de lucruri de verificat înainte de a-mi scoate părul!