Mitä tehdä Segmentointivirheelle 11
jostain syystä päätin rakentaa tuotteen pelkällä C: llä.jos tavoitteena oli koodaustehokkuus, se oli katastrofi. Mutta henkilökohtaisen kasvun välineenä uskon oppineeni samalla paljon enemmän ohjelmoinnista.
esimerkiksi tiedän nyt tarkemmin, miksi python-sanakirja ja lista käyttäytyvät eri tavalla, ja mitä se oikeastaan tarkoittaa ”pass by reference.”
kuitenkin, jos olisi yksi este, jonka vuoksi en koskaan haluaisi palata C: hen, se olisi pelätty ”Segmentation Fault 11”, jota seurasi tiiviisti ”Abort Trap 6.”
nämä kaksi virhettä tapahtuvat ajon aikana, jolloin niitä on vaikea debugata. XCode, Eclipse tai muut virheenkorjaus työkalut ovat todella hyödyllisiä, mutta olen oppinut, että se on paljon tärkeämpää oppia, mitä nämä asiat ovat ja keksiä menettelyjä puuttua virheenkorjaus prosessi. Tässä on vain muistiinpanoni omista tavallisista virheistäni. Toivon tehdä tästä vianmäärityslistan kaikille, joilla on omat ongelmansa. Haluan ainakin peittää typerät ongelmani, jotta voit keskittyä oikeisiin koodausongelmiin.
segmentointivirhe tarkoittaa, että ohjelmasi yritti päästä käsiksi johonkin, mitä sen ei pitänyt. Se on osa ongelmaa. On monia syitä, miksi ohjelma voi käyttää asioita, joita sen ei pitäisi, mutta kootussa koodissa lukee aika lailla vain ”#$#@^ * &!” sijaan. Jos asiaa miettii, ei haluaisi joutua selittämään eräälle, miksi hänen tökkimisensä herkässä kohdassa suututtaa. Haluat heidän vain lopettavan sen. Onneksi tietokoneet ovat sekä tyhmiä että yllättävän kärsivällisiä noin 75 vuoden insinöörityön jälkeen. He jatkavat Seg-vikojen lähettämistä, mutta (yleensä) eivät lakkaa olemasta ystäviä, kun se tapahtuu 1000.kerran.
mikä on Keskeytysloukku?
Ei se niin paljon eroa ole. Jossain tietokoneesi käski keskeyttää ohjelman. Taaskaan, ei kovin avulias. Yleensä se kuitenkin tapahtuu, kun yrittää tehdä jotain sellaista kuin access string
kaksimerkkisen merkkijonon "nw"
tai jättää varaamatta tarpeeksi muistia char string
merkkijonolle tai matriisille, kuten "way"
.
mitä Seg-Vialle pitäisi tehdä?
lukemani tutoriaalit keskittyvät yleensä vianetsintätyökalujen, kuten lldb: n, gdb: n ja niin edelleen, käyttöön. Sehän on hienoa. Kyllä, kannattaa ajaa gcc -g
ensin ja sitten lldb executable_name
ja sitten run -flag1 -flag2
, että auttaako se asian selvittämisessä. Mutta joskus apua ei ole lainkaan. Minulla on lista tarkistettavista asioista.
- Tarkista, että tarvittavilla ohjelmasi globaaleilla muuttujilla on arvot. Tämä tapahtui lähinnä siksi, että olin luonut liput, jotka täyttivät joukon arvoja, jotka piti asettaa ennen juoksua. Mutta entä jos he eivät laita mitään? Seg Fault 11! Oli useita kertoja olen * ajatellut * vars asetettu, kun ne eivät olleet ja että tehty haastavia vikoja. Vielä parempi on yrittää pitää globaalit niin, että niitä on helpompi seurata.
- malloc on sekä ystäväsi että vihollisesi. Varsinkin käyttäjämerkintöjen kanssa voi olla hyvin haastavaa jakaa muistia ja sitten kopioida, yhdistää ja tehdä mitä tahansa muuta matkan varrella. Tunne tämä komento hyvin ja miten se toimii. Ja älä unohda
free()
muistoa, kun olet valmis! - käytä
char var
määrittääksesi char*: n koon muistinjakoa varten. Suurin osa ongelmasta olin mukana määrittämällä muuttujia lopulta hyväksyä merkkijono. Olen nähnyt muita neuvoja, mutta jos sen merkkijono olet työskennellyt, mielestäni olistrlen()
toimi kaikkein johdonmukaisesti. Tarvitset + 1\0
(null) päättääksesi merkkijonon lopussa. - käytä
int arr) +1)]
muunlaisille ryhmille. Se on outo tapa tehdä asioita, mutta sen saa alatyylisellä kielenkäytöllä. -
\0
edustaa nollia ja päättää joukon. Se voi olla hyödyllistä, kun yrität estää puskurin ylivuoto ongelmia. - yritä käyttää määriteltyjä vakioita mahdollisimman paljon. Aina kun pystyt määrittelemään asioita precompile, se säästää vianetsintäaikaa myöhemmin.
- ymmärrä, mitä otsikkotiedostot ovat. Monet tutorials kertoo, mitä otsikkotiedosto sisältää,mutta ei ole aina selvää, mitä ne ovat. Otsikkotiedostot otetaan talteen ennen käännöstä ja ne antavat yhteenvedon muuttujista ja toiminnoista, jotka ovat ohjelman käytettävissä *ennen kuin se laatii*. Tämä tarkoittaa, että.ohjelmaan sisältyvät C-tiedostot voivat käyttää näitä toimintoja, kunhan
#include <headerfile.h>
lisätään tiedostoon. Hyvä yleissopimus on luoda .H-tiedosto kun luot .c-tiedosto, ja sisällytä se C: hen. - useimmat silmukat menevät näin:
for (int i=0; i < stop; i++)
helppo tapa saada keskeytysloukku on laittaa a ≤stop
. - pidä ongelmasi kurissa. Yritä tehdä se niin, että jokainen tiedosto tekee muutamia erillisiä asioita eikä mitään muuta. Jos sinun täytyy metsästää läpi eri tiedostoja yli ja noin, se voi tehdä löytää seg vika ongelmia todella vaikeaa.
- Tietokonematiikka on vaikeaa. Ei oikeastaan, mutta pienet asiat aiheuttavat isoja ongelmia.
char variable
esimerkiksi tarkoittaa joukkoa, joka sisältää kaksi alkiota, mutta koska indeksit alkavat 0: sta, se tarkoittaa, että voi mennä vain numeroon 1. - Print format strings oikeana tyyppinä. Onneksi tämä jää yleensä kiinni kääntöaikaan, mutta se voi silti aiheuttaa ongelmia. Varmista, että formaattimerkintäsi
%{whatever}
sopii mihin tahansa muuttujaan, jonka haluat siihen laittaa.
siinä kaikki, mitä minulla nyt on. Toivottavasti kärsimykseni ovat säästäneet sinut päänsäryltä. Jos kaikki muu epäonnistuu, minulla on nyt lista asioita tarkistaa ennen kuin vedän hiukset ulos!