Vad ska man göra med ett segmenteringsfel 11
av någon anledning bestämde jag mig för att bygga en produkt med vanlig C. Om målet var kodeffektivitet var det en katastrof. Men som ett verktyg för personlig tillväxt tror jag att jag lärde mig mycket mer om programmering i processen.
till exempel vet jag nu mer exakt varför en python-ordbok och en lista beter sig annorlunda, och vad det egentligen betyder att ”passera genom referens.”
men om det fanns en barriär som skulle få mig att aldrig vilja gå tillbaka till C, skulle det vara det fruktade ”Segmenteringsfelet 11”, följt noga av ”Avbryt fälla 6.”
dessa två fel uppstår under körtid, vilket gör dem svåra att felsöka. XCode, Eclipse eller andra felsökningsverktyg är verkligen användbara, men jag har lärt mig att det är mycket viktigare att lära sig vad dessa saker är och komma med procedurer för att ta itu med felsökningsprocessen. Detta är bara mina anteckningar om mina egna vanliga misstag. Jag hoppas att göra detta till en felsökningslista för alla som har sina egna problem. Jag vill åtminstone täcka mina dumma problem, så att du kan fokusera på verkliga kodningsproblem.
ett segmenteringsfel betyder att ditt program försökte komma åt något som det inte var tänkt att. Det är en del av problemet. Det finns många anledningar till att ett program kan komma åt saker som det inte ska, men sammanställd kod säger ganska mycket bara”#$#@^*&!” istället. Om du tänker på det, vill du inte behöva förklara för någon varför de pekar dig på en känslig plats gör dig arg. Du vill bara att de ska sluta göra det. Lyckligtvis är datorer både dumma och överraskande tålmodiga efter cirka 75 års teknik. De fortsätter att skicka Seg-fel, men (vanligtvis) slutar inte vara vänner efter att det händer 1000: e gången.
Vad är Abortfälla?
det är inte så mycket annorlunda. Någonstans sa din dator sig själv att avbryta programmet. Återigen, inte särskilt hjälpsam. Det inträffar dock vanligtvis när du försöker göra något som access string
av en två-char sträng "nw"
eller misslyckas med att tilldela tillräckligt med minne char string
för en sträng eller array som "way"
.
Vad ska du göra med ett Seg-fel?
handledningarna jag läser tenderar att fokusera på att använda felsökningsverktyg som lldb, gdb och så vidare. Det är allt bra och dandy. Ja, du bör köra gcc -g
först och sedan lldb executable_name
och sedan run -flag1 -flag2
för att se om det hjälper dig att räkna ut det. Men ibland finns det ingen hjälp alls. Jag har en lista över saker att kontrollera om.
- kontrollera att dina nödvändiga program globala variabler har värden. Detta hände mest för att jag hade skapat flaggor som fyllde i en massa värden som behövde ställas in innan de kördes. Men vad händer om de inte lägger in något? Seg Fel 11! Det fanns ett antal gånger jag * trodde * vars sattes när de inte var och det gjordes för utmanande buggar. Ännu bättre, försök att hålla globals till en gräns så att de är lättare att spåra.
- malloc är både din vän och din fiende. Speciellt med användarposter kan det vara mycket utmanande att allokera minne och sedan kopiera, sammanfoga och göra allt annat på vägen. Känn det här kommandot väl och hur det fungerar. Och glöm inte att
free()
minnet när du är klar! - använd
char var
för att bestämma storleken på en röding* för minnesallokering. Det mesta av problemet jag hade involverat att tilldela variabler för att så småningom acceptera en sträng. Jag har sett andra råd, men om det är en sträng du arbetar med, tror jag varstrlen()
arbetade mest konsekvent. Du behöver + 1 för\0
(null) för att avsluta strängen i slutet. - använd
int arr) +1)]
för matriser av andra typer. Det är ett konstigt sätt att göra saker, men det är vad du får med ett lågnivåspråk. -
\0
representerar null och avslutar en array. Det kan vara till hjälp när du försöker förhindra buffertspillproblem. - försök att använda definierade konstanter så mycket som möjligt. När du har möjlighet att definiera saker på precompile, det kommer att spara felsökning tid senare.
- förstå vad header-filer är till för. Många av handledningarna kommer att berätta vad en rubrikfil innehåller, men det är inte alltid klart vad de är för. Header filer fångas på pre-kompilera tid och ge en sammanfattning av variabler och funktioner som är tillgängliga för programmet *innan den sammanställer*. Detta innebär att .C-filer som ingår i programmet kommer att kunna komma åt dessa funktioner, förutsatt att
#include <headerfile.h>
läggs till i filen. En bra konvention är att skapa en .h-fil när du skapar en .C-fil, och inkludera den i c. - de flesta för loopar går så här:
for (int i=0; i < stop; i++)
ett enkelt sätt att få en abortfälla är att sätta en GHz framförstop
. - Håll dina problem inneslutna. Försök att göra det så att varje fil gör några diskreta saker och inget annat. Om du måste jaga igenom olika filer om och om kan det göra det svårt att hitta dina seg-felproblem.
- Datormatematik är svårt. Det är inte riktigt, men små saker orsakar stora problem.
char variable
betyder till exempel en array som innehåller två objekt, men eftersom index börjar vid 0 betyder det att du bara kan gå upp till nummer 1. - Skriv ut formatsträngar som rätt typ. Lyckligtvis fångas detta vanligtvis vid kompileringstiden, men det kan fortfarande orsaka problem. Se till att ditt formattecken
%{whatever}
passar vilken variabel du vill lägga in i den.
det är allt jag har för nu. Jag hoppas att mina elände har sparat dig lite huvudvärk på vägen! Om allt annat misslyckas har jag nu en lista över saker att kontrollera innan jag drar ut håret!