c errors undefined reference
Ta vadnica podrobno opisuje kritične napake, s katerimi se programerji pogosto srečujejo v jeziku C ++, kot so nedefinirana referenca, napaka segmentacije (dump jedro) in nerešen zunanji simbol:
Pogovorili se bomo o najpomembnejših napakah, ki jih v jeziku C ++ pogosto srečamo in so pravzaprav enako kritične. Poleg sistemskih in semantičnih napak in izjem, ki se občasno pojavljajo, dobimo tudi druge kritične napake, ki vplivajo na delovanje programov.
Te napake se večinoma pojavijo proti koncu programa med izvajanjem. Včasih program da ustrezen izhod in potem pride do napake.
=> Obiščite tukaj, če se želite naučiti C ++ iz nič.
Kaj se boste naučili:
Pomembne napake C ++
V tej vadnici bomo obravnavali tri vrste napak, ki so kritične z vidika katerega koli programerja C ++.
- Nedefinirana referenca
- Napaka segmentacije (jedro odloženo)
- Nerazrešen zunanji simbol
Pogovorili se bomo o možnih vzrokih za vsako od teh napak in skupaj z varnostnimi ukrepi, ki jih lahko kot programer uporabimo za preprečevanje teh napak.
Začnimo!!
Nedoločena referenca
Napaka »Nedoločena referenca« se pojavi, ko se v našem programu sklicujemo na ime predmeta (razred, funkcija, spremenljivka itd.) In povezovalnik ne more najti njegove definicije, ko ga poskuša iskati v vseh povezanih objektnih datotekah in knjižnicah .
Ko torej povezovalec ne najde definicije povezanega predmeta, izda napako »nedefinirana referenca«. Kot je razvidno iz definicije, se ta napaka pojavlja v poznejših fazah postopka povezovanja. Obstajajo različni razlogi, ki povzročajo napako »nedefinirana referenca«.
Nekatere od teh razlogov obravnavamo spodaj:
kaj lahko narediš s c ++
# 1) Za objekt ni predvidena definicija
To je najpreprostejši razlog za napako »nedefinirana referenca«. Programer je preprosto pozabil definirati objekt.
Razmislite o naslednjem programu C ++. Tu smo določili samo prototip funkcije in ga nato uporabili v glavni funkciji.
#include int func1(); int main() { func1(); }
Izhod:
Torej, ko prevedemo ta program, se pojavi napaka povezovalca, v kateri piše 'nedefinirano sklicevanje na' func1 () «.
Da bi se rešili te napake, program popravimo na naslednji način, tako da damo definicijo funkcije func1. Zdaj program daje ustrezen izhod.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Izhod:
Pozdravljen, svet!!
# 2) Napačna definicija (podpisi se ne ujemajo) uporabljenih predmetov
Še en vzrok za napako »nedefinirana referenca« je, če določimo napačne definicije. V našem programu uporabljamo kateri koli predmet, njegova definicija pa je nekaj drugačnega.
Razmislite o naslednjem programu C ++. Tukaj smo poklicali funkc1 (). Njegov prototip je int func1 (). Toda njegova opredelitev se ne ujema s prototipom. Kot vidimo, definicija funkcije vsebuje parameter funkcije.
Ko je program preveden, je prevajanje uspešno zaradi ujemanja prototipa in klica. Ko pa povezovalnik poskuša povezati klic funkcije s svojo definicijo, odkrije težavo in napako izda kot »nedefinirano referenco«.
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Izhod:
Da bi preprečili takšne napake, preprosto navzkrižno preverimo, ali se definicije in uporaba vseh predmetov ujemajo v našem programu.
# 3) Datoteke objektov niso pravilno povezane
Ta težava lahko povzroči tudi napako »nedefinirana referenca«. Tu imamo morda več izvornih datotek in jih lahko sestavimo neodvisno. Ko to storite, predmeti niso pravilno povezani in rezultat je 'nedefinirana referenca'.
Upoštevajte naslednja dva programa C ++. V prvi datoteki uporabimo funkcijo “print ()”, ki je definirana v drugi datoteki. Ko te datoteke zberemo ločeno, prva datoteka daje 'nedefinirano referenco' za tiskalno funkcijo, druga pa 'nedefinirano referenco' za glavno funkcijo.
int print(); int main() { print(); }
Izhod:
int print() { return 42; }
Izhod:
Način za odpravo te napake je sestavljanje obeh datotek hkrati ( Na primer, z uporabo g ++).
Poleg že obravnavanih vzrokov se lahko 'nedefinirana referenca' pojavi tudi iz naslednjih razlogov.
# 4) Napačna vrsta projekta
Ko v IDE-jih C ++, kot je vizualni studio, določimo napačne vrste projektov in poskušamo narediti stvari, ki jih projekt ne pričakuje, dobimo »nedefinirano referenco«.
# 5) Brez knjižnice
Če programer ni pravilno določil poti knjižnice ali je popolnoma pozabil določiti, dobimo iz knjižnice 'nedefinirano referenco' za vse reference, ki jih program uporablja.
# 6) Odvisne datoteke niso prevedene
Programer mora zagotoviti, da predhodno zberemo vse odvisnosti projekta, tako da pri prevajanju projekta prevajalnik najde vse odvisnosti in uspešno prevede. Če katera od odvisnosti manjka, potem prevajalnik poda 'nedefinirano referenco'.
Poleg zgoraj omenjenih vzrokov se lahko napaka 'nedefinirana referenca' pojavi tudi v mnogih drugih situacijah. Bottom line je, da je programer stvari zmotil in da bi to napako preprečil, jih je treba popraviti.
Napaka segmentacije (odvrženo jedro)
Napaka »napaka segmentacije (jedro je odstranjeno)« je napaka, ki kaže na poškodbe pomnilnika. Običajno se zgodi, ko poskušamo dostopati do pomnilnika, ki ne spada v obravnavani program.
Tu je nekaj razlogov, ki povzročajo napako v napaki segmentacije.
# 1) Spreminjanje konstantnega niza
Razmislite o naslednjem programu, v katerem smo razglasili konstanten niz. Nato poskusimo spremeniti ta konstantni niz. Ko se program zažene, dobimo napako, prikazano v izhodu.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Izhod:
# 2) Kazalec za preusmerjanje referenc
Kazalec mora usmeriti na veljavno mesto v pomnilniku, preden ga preimenujemo. V spodnjem programu vidimo, da kazalec kaže na NULL, kar pomeni, da je pomnilniška lokacija, na katero kaže, 0, tj. Neveljavna.
Torej, ko jo preusmerimo v naslednjo vrstico, dejansko poskušamo dostopati do njenega neznanega pomnilniškega mesta. To dejansko povzroči napako v segmentaciji.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Izhod:
Napaka segmentacije
Naslednji program prikazuje podoben primer. Tudi v tem programu kazalec ne kaže na veljavne podatke. Neinicializirani kazalec je tako dober kot NULL in zato kaže tudi na neznano lokacijo pomnilnika. Torej, ko ga poskušamo razporediti, privede do napake segmentacije.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Izhod:
Napaka segmentacije
Da bi preprečili takšne napake, moramo zagotoviti, da naše kazalne spremenljivke v programu vedno kažejo na veljavne pomnilniške lokacije.
# 3) Prelivanje skladov
Ko imamo v programu rekurzivne klice, ti požrejo ves pomnilnik v nizu in povzročijo prelivanje sklada. V takih primerih dobimo napako segmentacije, saj je zmanjšanje pomnilnika sklada tudi nekakšna poškodba pomnilnika.
Upoštevajte spodnji program, kjer izračunamo faktorijev števila rekurzivno. Upoštevajte, da naše osnovno stanje preizkusi, če je število 0 in nato vrne 1. Ta program deluje popolnoma za pozitivna števila.
Toda kaj se zgodi, ko dejansko prenesemo negativno število na faktorjsko funkcijo? No, ker osnovni pogoj ni podan za negativna števila, funkcija ne ve, kje bi se ustavila in tako povzroči prelivanje sklada.
To je prikazano v spodnjem izhodu, ki daje napako segmentacije.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Izhod:
Napaka segmentacije (jedro odloženo)
Da bi odpravili to napako, nekoliko spremenimo osnovno stanje in določimo tudi primer negativnih števil, kot je prikazano spodaj.
#include using namespace std; int factorial(int n) { // What about n <0? if(n <= 0) { return 1; } return factorial(n-1) * n; } int main() { cout<<'Factorial output:'< Izhod:
Faktorski izhod: 1
Zdaj vidimo, da je za segmentacijsko napako poskrbljeno in program deluje v redu.
Nerazrešen zunanji simbol
Nerazrešen zunanji simbol je napaka povezovalca, ki pomeni, da med postopkom povezovanja ne more najti simbola ali njegove reference. Napaka je podobna 'nedefinirani referenci' in je zamenljiva.
Spodaj smo navedli dva primera, v katerih lahko pride do te napake.
# 1) Ko v programu sklicujemo na spremenljivko strukture, ki vsebuje statičnega člana.
#include struct C { static int s; }; // int C::s; // Uncomment the following line to fix the error. int main() { C c; C::s = 1; }
Izhod:

V zgornjem programu ima struktura C statične člane s, ki niso dostopni zunanjim programom. Ko mu torej poskušamo dodeliti vrednost v glavni funkciji, povezovalnik ne najde simbola in lahko povzroči 'nerazrešen zunanji simbol' ali 'nedoločen sklic'.
Način, kako odpraviti to napako, je, da spremenljivko pred uporabo izrecno uporabite s pomočjo '::'.
# 2) Ko imamo v izvorni datoteki referenco na zunanje spremenljivke in nismo povezali datotek, ki definirajo te zunanje spremenljivke.
Ta primer je prikazan spodaj:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Izhod:
kako ustvariti graf v javi -

Na splošno v primeru »nerazrešenega zunanjega simbola« prevedena koda za kateri koli objekt, kot je funkcija, ne najde simbola, na katerega se sklicuje, morda zato, ker ta simbol ni opredeljen v objektnih datotekah ali kateri koli knjižnici določeno povezovalniku.
Zaključek
V tej vadnici smo razpravljali o nekaterih večjih napakah v jeziku C ++, ki so kritične in lahko vplivajo na pretok programa in lahko celo povzročijo zrušitev aplikacije. Podrobno smo raziskali vse o napaki segmentacije, nerazrešenem zunanjem simbolu in nedoločeni referenci.
Čeprav se te napake lahko pojavijo kadar koli, že iz vzrokov, o katerih smo razpravljali, vemo, da jih lahko enostavno preprečimo s skrbnim razvojem našega programa.
=> Preberite serijo Easy C ++ Training Series.
Priporočeno branje