c errors undefined reference
vad är testning av användaraccept vid testning av programvara
Denna handledning beskriver de kritiska fel som programmerare ofta stöter på i C ++ som Odefinierad referens, ett segmenteringsfel (core dumpad) och olöst extern symbol:
Vi kommer att diskutera de viktigaste felen som vi ofta stöter på i C ++ som verkligen är lika kritiska. Förutom system- och semantiska fel och undantag som uppstår då och då, får vi också andra kritiska fel som påverkar driften av program.
Dessa fel uppstår oftast mot slutet av programmet vid körning. Ibland ger programmet korrekt utgång och då inträffar felet.
=> Besök här för att lära dig C ++ från Scratch.
Vad du kommer att lära dig:
Viktiga C ++ - fel
I den här handledningen kommer vi att diskutera tre typer av fel som är kritiska ur C ++ programmerares synvinkel.
- Obestämd hänvisning
- Segmenteringsfel (kärna dumpad)
- Olöst extern symbol
Vi kommer att diskutera de möjliga orsakerna till vart och ett av dessa fel och tillsammans med de försiktighetsåtgärder som vi kan vidta som programmerare för att förhindra dessa fel.
Låt oss börja!!
Obestämd hänvisning
Ett 'Odefinierad referens' -fel inträffar när vi har en referens till objektnamn (klass, funktion, variabel etc.) i vårt program och länkaren kan inte hitta sin definition när den försöker söka efter det i alla länkade objektfiler och bibliotek .
Således när länkaren inte kan hitta definitionen av ett länkat objekt, utfärdar det ett 'odefinierad referens' -fel. Som klart framgår av definitionen inträffar detta fel i de senare stadierna av länkningsprocessen. Det finns olika orsaker som orsakar ett 'odefinierad referens' -fel.
Vi diskuterar några av dessa skäl nedan:
# 1) Ingen definition tillhandahålls för objekt
Detta är det enklaste skälet till att orsaka ett 'odefinierad referens' -fel. Programmeraren har helt enkelt glömt att definiera objektet.
Tänk på följande C ++ - program. Här har vi bara specificerat prototypen för funktionen och sedan använt den i huvudfunktionen.
#include int func1(); int main() { func1(); }
Produktion:
Så när vi kompilerar det här programmet utfärdas länkfelet som säger 'odefinierad referens till' func1 () ''.
För att bli av med detta fel korrigerar vi programmet enligt följande genom att tillhandahålla definitionen av funktionen func1. Nu ger programmet rätt utdata.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Produktion:
Hej världen!!
# 2) Fel definition (signaturer matchar inte) Använda objekt
Ytterligare en orsak till 'odefinierad referens' -fel är när vi anger fel definitioner. Vi använder alla objekt i vårt program och dess definition är något annorlunda.
Tänk på följande C ++ - program. Här har vi ringt till func1 (). Dess prototyp är int func1 (). Men dess definition överensstämmer inte med dess prototyp. Som vi ser innehåller definitionen av funktionen en parameter för funktionen.
Således när programmet kompileras lyckas kompileringen på grund av matchning av prototyp och funktionssamtal. Men när länkaren försöker länka funktionsanropet med sin definition, finner den problemet och ger felet som 'odefinierad referens'.
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Produktion:
För att förhindra sådana fel korsar vi helt enkelt om definitionerna och användningen av alla objekt matchar i vårt program.
# 3) Objektfiler länkas inte ordentligt
Denna fråga kan också ge upphov till 'odefinierad referens' -fel. Här kan vi ha mer än en källfil och vi kan sammanställa dem oberoende. När detta är gjort är objekten inte länkade ordentligt och det resulterar i ”odefinierad referens”.
Tänk på följande två C ++ - program. I den första filen använder vi funktionen “print ()” som definieras i den andra filen. När vi sammanställer dessa filer separat, ger den första filen 'odefinierad referens' för utskriftsfunktionen, medan den andra filen ger 'odefinierad referens' för huvudfunktionen.
int print(); int main() { print(); }
Produktion:
int print() { return 42; }
Produktion:
Sättet att lösa detta fel är att kompilera båda filerna samtidigt ( Till exempel, genom att använda g ++).
Förutom orsakerna som redan diskuterats kan ”odefinierad referens” också uppstå av följande skäl.
# 4) Fel projekttyp
När vi specificerar fel projekttyper i C ++ IDE som den visuella studion och försöker göra saker som projektet inte förväntar sig får vi 'odefinierad referens'.
# 5) Inget bibliotek
Om en programmerare inte har specificerat sökvägen ordentligt eller helt glömt att specificera den, får vi en 'odefinierad referens' för alla referenser som programmet använder från biblioteket.
# 6) Beroende filer kompileras inte
En programmerare måste se till att vi kompilerar alla beroenden i projektet i förväg så att kompilatorn hittar alla beroenden och kompilerar framgångsrikt när vi kompilerar projektet. Om något av beroenden saknas ger kompilatorn 'odefinierad referens'.
Bortsett från orsakerna som diskuterats ovan kan 'odefinierad referens' -fel uppstå i många andra situationer. Men i grund och botten är att programmeraren har fått saker och ting fel och för att förhindra detta fel bör de korrigeras.
java lägg till i slutet av matrisen
Segmenteringsfel (kärna dumpad)
Felet 'segmenteringsfel (core dumped)' är ett fel som indikerar minneskorruption. Det inträffar vanligtvis när vi försöker komma åt ett minne som inte tillhör programmet.
Här är några av anledningarna som orsakar fel i segmenteringsfel.
# 1) Ändra den konstanta strängen
Tänk på följande program där vi har förklarat en konstant sträng. Sedan försöker vi ändra den här konstanta strängen. När programmet körs får vi felet som visas i utdata.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Produktion:
# 2) Referenspekare
En pekare måste peka på en giltig minnesplats innan vi refererar till den. I programmet nedan ser vi att pekaren pekar på NULL vilket betyder att minnesplatsen den pekar på är 0, dvs. ogiltig.
Därför försöker vi faktiskt komma åt dess okända minnesplats när vi avläser det i nästa rad. Detta resulterar verkligen i ett segmenteringsfel.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Produktion:
Segmenteringsfel
Nästa program visar ett liknande fall. Även i detta program pekar inte pekaren på giltiga data. En oinitialiserad pekare är lika bra som NULL och pekar därför också på okänd minnesplats. Således när vi försöker att avlägsna det, resulterar det i ett segmenteringsfel.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Produktion:
Segmenteringsfel
För att förhindra sådana fel måste vi se till att våra pekervariabler i programmet alltid pekar på giltiga minnesplatser.
# 3) Stacköverflöde
hur man ringer en array från en annan metod i java
När vi har rekursiva samtal i vårt program äter de upp allt minne i stacken och får stacken att rinna över. I sådana fall får vi segmenteringsfelet eftersom det går att ta slut på stackminnet också är ett slags minneskorruption.
Tänk på nedanstående program där vi beräknar fakturan för ett nummer rekursivt. Observera att vårt basvillkor testar om antalet är 0 och sedan returnerar 1. Detta program fungerar perfekt för positiva siffror.
Men vad händer när vi faktiskt överför ett negativt tal till en faktorfunktion? Eftersom basvillkoret inte anges för de negativa siffrorna, vet funktionen inte var den ska stoppas och resulterar således i ett stacköverflöde.
Detta visas i utgången nedan som ger segmenteringsfel.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Produktion:
Segmenteringsfel (kärna dumpad)
För att åtgärda detta fel ändrar vi basvillkoren något och anger också fallet för negativa siffror som visas nedan.
#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:'< Produktion:
Fabriksutgång: 1
Nu ser vi att segmenteringsfelet tas om hand och programmet fungerar bra.
Olöst extern symbol
Den olösta externa symbolen är ett länkfel som indikerar att den inte kan hitta symbolen eller dess referens under länkningsprocessen. Felet liknar ”odefinierad referens” och utfärdas omväxlande.
Vi har gett två fall nedan där detta fel kan uppstå.
# 1) När vi hänvisar till en strukturvariabel i programmet som innehåller en statisk medlem.
#include struct C { static int s; }; // int C::s; // Uncomment the following line to fix the error. int main() { C c; C::s = 1; }
Produktion:

I ovanstående program har struktur C en statisk medlem som inte är tillgänglig för de externa programmen. Så när vi försöker tilldela det ett värde i huvudfunktionen, hittar länkaren inte symbolen och kan resultera i en 'olöst extern symbol' eller 'odefinierad referens'.
Sättet att åtgärda detta fel är att uttryckligen omfatta variabeln med hjälp av '::' utanför huvudminnet innan du använder den.
# 2) När vi har externa variabler refererade till i källfilen och vi har inte länkat filerna som definierar dessa externa variabler.
Detta fall demonstreras nedan:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Produktion:

I allmänhet, i fallet med en 'olöst extern symbol', misslyckas den sammanställda koden för något objekt som en funktion att hitta en symbol som den hänvisar till, kanske för att den symbolen inte är definierad i objektfilerna eller något av biblioteken specificeras för länken.
Slutsats
I denna handledning diskuterade vi några stora fel i C ++ som är kritiska och kan påverka programflödet och till och med kan resultera i en applikationskrasch. Vi undersökte allt om segmenteringsfel, olöst extern symbol och odefinierad referens i detalj.
Även om dessa fel kan uppstå när som helst, av orsakerna som vi diskuterade vet vi att vi lätt kan förhindra dem genom att noggrant utveckla vårt program.
=> Läs igenom Easy C ++ Training Series.
Rekommenderad läsning