c errors undefined reference
Ovaj vodič detaljno opisuje kritične pogreške s kojima se programeri često susreću u C ++-u, poput Nedefinirane reference, greške segmentacije (bačena jezgra) i neriješenog vanjskog simbola:
Razgovarat ćemo o najvažnijim pogreškama s kojima se često susrećemo u C ++-u, a koje su uistinu jednako kritične. Osim sistemskih i semantičkih pogrešaka i iznimki koje se s vremena na vrijeme javljaju, dobivamo i druge kritične pogreške koje utječu na izvođenje programa.
Te se pogreške uglavnom javljaju prema kraju programa u vrijeme izvođenja. Ponekad program daje ispravan izlaz i tada se dogodi pogreška.
=> Posjetite ovdje da biste C ++ naučili od nule.
Što ćete naučiti:
Važne C ++ pogreške
U ovom uputstvu raspravit ćemo o tri vrste pogrešaka koje su kritične sa stajališta bilo kojeg programera C ++.
- Nedefinirana referenca
- Kvar segmentacije (jezgra bačena)
- Neriješeni vanjski simbol
Razgovarat ćemo o mogućim uzrocima svake od ovih pogrešaka i zajedno s mjerama predostrožnosti koje možemo poduzeti kao programer da bismo spriječili te pogreške.
Počnimo!!
Nedefinirana referenca
Pogreška 'Nedefinirana referenca' događa se kada u našem programu imamo referencu na ime objekta (klasa, funkcija, varijabla itd.), A povezivač ne može pronaći njegovu definiciju kada ga pokušava potražiti u svim povezanim objektnim datotekama i knjižnicama .
Stoga, kada povezivač ne može pronaći definiciju povezanog objekta, izdaje pogrešku 'nedefinirana referenca'. Kao što je jasno iz definicije, ova se pogreška javlja u kasnijim fazama postupka povezivanja. Postoje razni razlozi koji uzrokuju pogrešku 'nedefinirana referenca'.
Neke od ovih razloga razmatramo u nastavku:
# 1) Za objekt nije navedena definicija
To je najjednostavniji razlog uzrokovanja pogreške 'nedefinirane reference'. Programer je jednostavno zaboravio definirati objekt.
Razmotrite sljedeći program C ++. Ovdje smo samo naveli prototip funkcije i zatim ga koristili u glavnoj funkciji.
#include int func1(); int main() { func1(); }
Izlaz:
Dakle, kada kompajliramo ovaj program, izdaje se pogreška povezivača koja kaže 'nedefinirana referenca na 'func1 ()''.
Da bismo se riješili ove pogreške, ispravljamo program na sljedeći način dajući definiciju funkcije func1. Sada program daje odgovarajući izlaz.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Izlaz:
što možete učiniti s c ++-om
Pozdrav svijete!!
# 2) Pogrešna definicija (potpisi se ne podudaraju) korištenih objekata
Još jedan uzrok pogreške 'nedefinirane reference' je kada odredimo pogrešne definicije. U našem programu koristimo bilo koji objekt i njegova je definicija nešto drugo.
Razmotrite sljedeći program C ++. Ovdje smo uputili poziv funkc1 (). Njegov prototip je int func1 (). Ali njegova se definicija ne podudara s prototipom. Kao što vidimo, definicija funkcije sadrži parametar funkcije.
Dakle, kad je program kompiliran, kompilacija je uspješna zbog podudaranja prototipa i poziva funkcije. Ali kada povezivač pokušava povezati poziv funkcije s njegovom definicijom, pronalazi problem i izdaje pogrešku kao 'nedefiniranu referencu'.
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Izlaz:
Stoga da bismo spriječili takve pogreške, jednostavno provjeravamo podudaraju li se definicije i upotreba svih objekata u našem programu.
# 3) Datoteke objekata nisu pravilno povezane
Ovaj problem također može dovesti do pogreške 'nedefinirana referenca'. Ovdje možemo imati više izvornih datoteka i možda ih neovisno kompajliramo. Kada se to učini, objekti nisu pravilno povezani i rezultira 'nedefiniranom referencom'.
Razmotrite sljedeća dva programa C ++. U prvoj datoteci koristimo funkciju 'print ()' koja je definirana u drugoj datoteci. Kada te datoteke kompajliramo odvojeno, prva datoteka daje 'nedefiniranu referencu' za funkciju ispisa, dok druga datoteka daje 'nedefiniranu referencu' za glavnu funkciju.
int print(); int main() { print(); }
Izlaz:
int print() { return 42; }
Izlaz:
Način za rješavanje ove pogreške je istovremeno kompajliranje obje datoteke ( Na primjer, pomoću g ++).
Osim o već spomenutim uzrocima, 'nedefinirana referenca' može se pojaviti i iz sljedećih razloga.
# 4) Pogrešan tip projekta
Kad odredimo pogrešne vrste projekata u C ++ IDE-ima poput vizualnog studija i pokušamo učiniti stvari koje projekt ne očekuje, tada ćemo dobiti 'nedefiniranu referencu'.
# 5) Nema knjižnice
Ako programer nije pravilno odredio put knjižnice ili je potpuno zaboravio navesti, tada iz biblioteke dobivamo 'nedefiniranu referencu' za sve reference koje program koristi.
# 6) Zavisne datoteke nisu prevedene
Programer mora osigurati da prethodno kompajliramo sve ovisnosti projekta, tako da kad kompajliramo projekt, kompajler pronalazi sve ovisnosti i uspješno kompajlira. Ako bilo koja od ovisnosti nedostaje, tada prevodilac daje 'nedefiniranu referencu'.
Osim gore spomenutih uzroka, pogreška 'nedefinirana referenca' može se pojaviti u mnogim drugim situacijama. Dno svega je da je programer pogrešno shvatio stvari i da bi spriječio ovu pogrešku, trebalo bi ih ispraviti.
Kvar segmentacije (bačena jezgra)
Pogreška 'greška segmentacije (jezgra izbačena)' pogreška je koja ukazuje na oštećenje memorije. Obično se događa kada pokušamo pristupiti memoriji koja ne pripada programu koji se razmatra.
Evo nekoliko razloga koji uzrokuju pogrešku u pogrešci segmentacije.
# 1) Izmjena konstantnog niza
Razmotrite sljedeći program u kojem smo proglasili konstantni niz. Zatim pokušavamo modificirati ovaj konstantni niz. Kada se program izvrši, dobit ćemo pogrešku prikazanu u izlazu.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Izlaz:
# 2) Pokazivač za preusmjeravanje reference
Pokazivač mora usmjeriti na važeće memorijsko mjesto prije nego što ga odznačimo. U donjem programu vidimo da pokazivač pokazuje na NULL što znači da je memorijsko mjesto na koje pokazuje 0, tj. Nevaljano.
Stoga, kada ga preusmjeravamo u sljedeći redak, zapravo pokušavamo pristupiti njegovom nepoznatom memorijskom mjestu. To doista rezultira pogreškom segmentacije.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Izlaz:
Greška segmentacije
Sljedeći program prikazuje sličan slučaj. U ovom programu također pokazivač ne pokazuje valjane podatke. Neinicijalizirani pokazivač dobar je kao NULL i stoga upućuje na nepoznato mjesto memorije. Stoga, kada ga pokušamo razgraničiti, rezultira pogreškom segmentacije.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Izlaz:
Greška segmentacije
Da bismo spriječili takve pogreške, moramo osigurati da naše varijable pokazivača u programu uvijek usmjeravaju na važeće memorijske lokacije.
# 3) Preljev stoga
Kada u našem programu imamo rekurzivne pozive, oni pojedu svu memoriju u hrpi i uzrokuju preljev stoga. U takvim slučajevima dobivamo grešku segmentacije jer je ponestajanje memorije steka također vrsta oštećenja memorije.
Razmotrite donji program u kojem izračunavamo faktorijel broja rekurzivno. Imajte na umu da naše osnovno stanje testira je li broj 0, a zatim vraća 1. Ovaj program savršeno radi za pozitivne brojeve.
Ali što se događa kada zapravo prenesemo negativni broj na faktorsku funkciju? Pa, kako osnovni uvjet nije naveden za negativne brojeve, funkcija ne zna gdje se zaustaviti i time rezultira preljevom stoga.
To je prikazano u donjem izlazu koji daje grešku u segmentaciji.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Izlaz:
Kvar segmentacije (jezgra bačena)
Sada da bismo popravili ovu pogrešku, malo mijenjamo osnovno stanje i također specificiramo slučaj negativnih brojeva kao što je prikazano u nastavku.
#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:'< Izlaz:
Faktorski izlaz: 1
Sada vidimo da je riješena greška segmentacije i da program radi u redu.
Neriješeni vanjski simbol
Neriješeni vanjski simbol pogreška je povezivača koja ukazuje da ne može pronaći simbol ili njegovu referencu tijekom postupka povezivanja. Pogreška je slična 'nedefiniranoj referenci' i izdaje se naizmjenično.
U nastavku smo naveli dva slučaja u kojima se ova pogreška može dogoditi.
# 1) Kada upućujemo na strukturnu varijablu u programu koja sadrži statičkog č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; }
Izlaz:

U gornjem programu struktura C ima statičke članove s koji nisu dostupni vanjskim programima. Dakle, kada mu pokušamo dodijeliti vrijednost u glavnoj funkciji, povezivač ne pronalazi simbol i može rezultirati 'neriješenim vanjskim simbolom' ili 'nedefiniranom referencom'.
Način kako popraviti ovu pogrešku je da se prije korištenja varijable izričito koristi '::' izvan glavne.
# 2) Kada imamo vanjske varijable na koje se poziva izvorna datoteka, a nismo povezali datoteke koje definiraju te vanjske varijable.
Ovaj slučaj je prikazan u nastavku:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Izlaz:
sql pitanja za intervju za 3 godine iskustva

Općenito, u slučaju 'neriješenog vanjskog simbola', kompajlirani kod za bilo koji objekt poput funkcije ne uspije pronaći simbol na koji se poziva, možda zato što taj simbol nije definiran u objektnim datotekama ili bilo kojoj knjižnici naznačeno povezivaču.
Zaključak
U ovom smo uputstvu raspravljali o nekim glavnim pogreškama u C ++-u koje su kritične i mogu utjecati na tijek programa, a mogu čak rezultirati padom aplikacije. Detaljno smo istražili sve o pogrešci segmentacije, neriješenom vanjskom simbolu i Nedefiniranoj referenci.
Iako se ove pogreške mogu dogoditi bilo kada, iz uzroka o kojima smo razgovarali znamo da ih lako možemo spriječiti pažljivim razvojem našeg programa.
=> Pročitajte seriju Easy C ++ Training Series.
Preporučena literatura