c errors undefined reference
Tento tutoriál podrobne popisuje kritické chyby, s ktorými sa programátori často stretávajú v C ++, ako napríklad Nedefinovaná referencia, Chyba segmentácie (výpis z jadra) a Nevyriešený externý symbol:
Budeme diskutovať o najdôležitejších chybách, s ktorými sa často stretávame v C ++ a ktoré sú skutočne rovnako kritické. Okrem systémových a sémantických chýb a výnimiek, ktoré sa z času na čas vyskytnú, dostaneme aj ďalšie kritické chyby, ktoré ovplyvňujú chod programov.
Tieto chyby sa väčšinou vyskytujú na konci programu za behu programu. Program niekedy poskytuje správny výstup a potom dôjde k chybe.
=> Navštívte tu a dozviete sa C ++ od nuly.
Čo sa dozviete:
Dôležité chyby C ++
V tomto tutoriáli sa budeme zaoberať tromi typmi chýb, ktoré sú kritické z pohľadu ktoréhokoľvek programátora v C ++.
- Nedefinovaný odkaz
- Porucha segmentácie (jadro vyhodené)
- Nevyriešený vonkajší symbol
Budeme diskutovať o možných príčinách každej z týchto chýb a spolu s preventívnymi opatreniami, ktoré môžeme prijať ako programátor pri predchádzaní týmto chybám.
Začnime!!
Nedefinovaný odkaz
Chyba „Nedefinovaný odkaz“ sa vyskytne, keď máme v našom programe odkaz na názov objektu (trieda, funkcia, premenná atď.) A linker nemôže nájsť svoju definíciu, keď sa ho pokúša vyhľadať vo všetkých súboroch a knižniciach prepojených objektov. .
Keď teda linker nenájde definíciu prepojeného objektu, vydá chybu „nedefinovaný odkaz“. Ako je zrejmé z definície, k tejto chybe dochádza v neskorších fázach procesu prepájania. Existuje niekoľko dôvodov, ktoré spôsobujú chybu „nedefinovaná referencia“.
Niektoré z týchto dôvodov rozoberáme nižšie:
# 1) Pre objekt nie je poskytnutá žiadna definícia
Toto je najjednoduchší dôvod spôsobenia chyby „nedefinovaného odkazu“. Programátor jednoducho zabudol definovať objekt.
Zvážte nasledujúci program C ++. Tu sme iba špecifikovali prototyp funkcie a potom sme ju použili v hlavnej funkcii.
#include int func1(); int main() { func1(); }
Výkon:
Keď teda zostavíme tento program, vyskytne sa chyba linkera, ktorá hovorí „nedefinovaný odkaz na‘ func1 () ’“.
Aby sme sa tejto chyby zbavili, program opravíme nasledovne poskytnutím definície funkcie func1. Teraz program poskytuje príslušný výstup.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Výkon:
ahoj, svet !!
# 2) Nesprávna definícia (podpisy sa nezhodujú) použitých objektov
Ďalšou príčinou chyby „nedefinovaného odkazu“ je, keď zadáme nesprávne definície. V našom programe používame akýkoľvek objekt a jeho definícia je iná.
Zvážte nasledujúci program C ++. Tu sme volali func1 (). Jeho prototyp je int func1 (). Jeho definícia sa však nezhoduje s prototypom. Ako vidíme, definícia funkcie obsahuje parameter funkcie.
Takže keď je program kompilovaný, kompilácia je úspešná z dôvodu zhody prototypu a volania funkcie. Ale keď sa linker pokúša spojiť volanie funkcie s jeho definíciou, nájde problém a vydá chybu ako „nedefinovaný odkaz“.
bezplatný jednoduchý prevodník z youtube na mp3
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Výkon:
Aby sme týmto chybám zabránili, jednoducho skontrolujeme, či sa v našom programe zhodujú definície a použitie všetkých objektov.
# 3) Súbory objektov nie sú správne prepojené
Táto otázka môže tiež viesť k chybe „nedefinovaného odkazu“. Tu môžeme mať viac ako jeden zdrojový súbor a môžeme ho zostaviť samostatne. Keď to urobíte, objekty nie sú správne prepojené a výsledkom je „nedefinovaný odkaz“.
Zvážte nasledujúce dva programy C ++. V prvom súbore využívame funkciu „print ()“, ktorá je definovaná v druhom súbore. Keď tieto súbory zostavujeme osobitne, prvý súbor dáva „nedefinovaný odkaz“ pre funkciu tlače, zatiaľ čo druhý súbor dáva „nedefinovaný odkaz“ pre hlavnú funkciu.
int print(); int main() { print(); }
Výkon:
int print() { return 42; }
Výkon:
Spôsob, ako vyriešiť túto chybu, je kompilácia oboch súborov súčasne ( Napríklad, pomocou g ++).
Okrem už diskutovaných príčin sa môže vyskytnúť „nedefinovaný odkaz“ aj z nasledujúcich dôvodov.
# 4) Nesprávny typ projektu
Keď zadáme nesprávne typy projektov v C ++ IDE, ako je napríklad Visual Studio, a pokúsime sa robiť veci, ktoré projekt neočakáva, dostaneme „nedefinovaný odkaz“.
# 5) Žiadna knižnica
Ak programátor nezadal cestu ku knižnici správne alebo ju úplne zabudol zadať, dostaneme „nedefinovaný odkaz“ pre všetky odkazy, ktoré program z knižnice použije.
# 6) Závislé súbory nie sú kompilované
Programátor musí zabezpečiť, aby sme vopred zostavili všetky závislosti projektu, aby kompilátor pri zostavovaní projektu našiel všetky závislosti a úspešne sa zostavil. Ak niektorá zo závislostí chýba, kompilátor dá „nedefinovaný odkaz“.
Okrem vyššie diskutovaných príčin sa chyba „nedefinovaného odkazu“ môže vyskytnúť v mnohých ďalších situáciách. Záverom ale je, že programátor urobil chybu zle, a aby sa tejto chybe zabránilo, mali by sa opraviť.
Porucha segmentácie (vyradené jadro)
Chyba „chyba segmentácie (vyhodené jadro)“ je chyba, ktorá naznačuje poškodenie pamäte. Spravidla k tomu dôjde, keď sa pokúsime získať prístup do pamäte, ktorá do úvahy nepatrí.
Tu sú niektoré z dôvodov, ktoré spôsobujú chybu chyby segmentácie.
# 1) Úprava konštantného reťazca
Zvážte nasledujúci program, v ktorom sme deklarovali konštantný reťazec. Potom sa pokúsime upraviť tento konštantný reťazec. Keď je program vykonaný, dostaneme chybu zobrazenú na výstupe.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Výkon:
# 2) Dereferenčný ukazovateľ
Ukazovateľ musí ukazovať na platné miesto v pamäti skôr, ako ho dereferujeme. V nasledujúcom programe vidíme, že ukazovateľ smeruje na hodnotu NULL, čo znamená, že umiestnenie v pamäti, na ktoré ukazuje, je 0, teda neplatné.
Preto keď to dereferujeme v ďalšom riadku, skutočne sa pokúšame získať prístup k jeho neznámemu umiestneniu v pamäti. To skutočne vedie k poruche segmentácie.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Výkon:
Porucha segmentácie
Nasledujúci program ukazuje podobný prípad. Ukazovateľ ani v tomto programe neukazuje na platné údaje. Neinicializovaný ukazovateľ je rovnako dobrý ako NULL, a preto tiež ukazuje na neznáme umiestnenie v pamäti. Keď sa ho teda pokúsime dereferovať, vedie to k chybe segmentácie.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Výkon:
Porucha segmentácie
Aby sme takýmto chybám zabránili, musíme sa ubezpečiť, že naše premenné ukazovateľa v programe smerujú vždy na platné miesta v pamäti.
# 3) Pretekanie zásobníka
Keď máme v našom programe rekurzívne volania, zjedia všetku pamäť v zásobníku a spôsobia pretečenie zásobníka. V takýchto prípadoch dostaneme chybu segmentácie, pretože vyčerpanie pamäte zásobníka je tiež druhom poškodenia pamäte.
Zvážte nasledujúci program, v ktorom vypočítame faktoriál čísla rekurzívne. Upozorňujeme, že naša základná podmienka testuje, či je číslo 0, a potom vráti 1. Tento program funguje perfektne pre kladné čísla.
Čo sa však stane, keď skutočne odovzdáme záporné číslo faktoriálnej funkcii? Pretože základná podmienka nie je daná zápornými číslami, funkcia nevie, kde sa má zastaviť, a vedie tak k pretečeniu zásobníka.
Toto sa zobrazuje na výstupe nižšie, ktorý spôsobuje poruchu segmentácie.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Výkon:
Porucha segmentácie (jadro vyhodené)
Teraz, aby sme túto chybu opravili, mierne zmeníme základnú podmienku a tiež zadáme veľkosť záporných čísel, ako je uvedené nižšie.
#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:'< Výkon:
Faktorový výstup: 1
Teraz vidíme, že o poruchu segmentácie je postarané a program funguje dobre.
Nevyriešený externý symbol
Nevyriešený externý symbol je chyba linkera, ktorá naznačuje, že počas procesu prepájania nemôže nájsť symbol alebo jeho odkaz. Chyba je podobná ako „nedefinovaná referencia“ a je vydávaná zameniteľne.
Nižšie uvádzame dva prípady, kedy môže k tejto chybe dôjsť.
# 1) Keď odkazujeme na premennú štruktúry v programe, ktorá obsahuje statický člen.
#include struct C { static int s; }; // int C::s; // Uncomment the following line to fix the error. int main() { C c; C::s = 1; }
Výkon:

Vo vyššie uvedenom programe má štruktúra C statické členy, ktoré nie sú prístupné vonkajším programom. Keď sa mu teda pokúsime priradiť hodnotu v hlavnej funkcii, linker nenájde symbol a môže mať za následok „nevyriešený externý symbol“ alebo „nedefinovaný odkaz“.
Túto chybu je možné opraviť tak, že pred použitím explicitne nastavíte rozsah premennej pomocou znaku „::“ mimo hlavnej premennej.
# 2) Keď máme v zdrojovom súbore odkazované externé premenné a neprepojili sme súbory, ktoré tieto externé premenné definujú.
Tento prípad je demonštrovaný nižšie:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Výkon:

Všeobecne platí, že v prípade „nevyriešeného externého symbolu“ kompilovaný kód pre ľubovoľnú funkciu podobný objektu nedokáže nájsť symbol, na ktorý odkazuje, možno preto, že tento symbol nie je definovaný v súboroch objektov ani v žiadnej z knižníc. určený linkerovi.
Záver
V tomto tutoriáli sme diskutovali o niekoľkých závažných chybách v C ++, ktoré sú kritické a môžu ovplyvniť tok programu a môžu dokonca viesť k zlyhaniu aplikácie. Podrobne sme preskúmali všetko o chybe segmentácie, nevyriešenom externom symbole a nedefinovanej referencii.
Aj keď sa tieto chyby môžu vyskytnúť kedykoľvek, z príčin, o ktorých sme diskutovali, vieme, že im môžeme ľahko zabrániť starostlivým vývojom nášho programu.
=> Prečítajte si sériu Easy C ++ Training Series.
Odporúčané čítanie