c errors undefined reference
най-доброто облачно съхранение за големи файлове
Този урок описва критичните грешки, с които програмистите често се сблъскват в C ++, като Недефинирана препратка, Сегментационна грешка (изхвърлено ядро) и Нерешен външен символ:
Ще обсъдим най-важните грешки, които често срещаме в C ++, които са също толкова критични. Освен системните и семантични грешки и изключения, които се появяват от време на време, получаваме и други критични грешки, които засягат работата на програмите.
Тези грешки се появяват най-вече към края на програмата по време на изпълнение. Понякога програмата дава правилен изход и тогава възниква грешката.
=> Посетете тук, за да научите C ++ от нулата.
Какво ще научите:
Важни грешки в C ++
В този урок ще обсъдим три вида грешки, които са критични от гледна точка на всеки програмист на C ++.
- Недефинирана препратка
- Грешка в сегментирането (изхвърлено ядро)
- Неразрешен външен символ
Ще обсъдим възможните причини за всяка от тези грешки и заедно с предпазните мерки, които можем да вземем като програмист, за да предотвратим тези грешки.
Да започваме!!
Неопределена справка
Грешка „Недефинирана референция“ възниква, когато имаме препратка към име на обект (клас, функция, променлива и т.н.) в нашата програма и линкерът не може да намери дефиницията му, когато се опитва да го търси във всички свързани обектни файлове и библиотеки .
По този начин, когато линкерът не може да намери дефиницията на свързан обект, той издава грешка „недефинирана препратка“. Както става ясно от дефиницията, тази грешка възниква в по-късните етапи на процеса на свързване. Има различни причини, които причиняват грешка „недефинирана препратка“.
Ние обсъждаме някои от тези причини по-долу:
# 1) Не е предоставена дефиниция за обект
Това е най-простата причина за причиняване на грешка „недефинирана препратка“. Програмистът просто е забравил да дефинира обекта.
Помислете за следната програма на C ++. Тук ние само посочихме прототипа на функцията и след това го използвахме в основната функция.
#include int func1(); int main() { func1(); }
Изход:
Така че, когато компилираме тази програма, се издава грешка на свързващото устройство, която казва „недефинирана препратка към‘ func1 () ’“.
За да се отървем от тази грешка, ние коригираме програмата, както следва, като предоставим дефиницията на функцията func1. Сега програмата дава съответния изход.
#include using namespace std; int func1(); int main() { func1(); } int func1(){ cout<<'hello, world!!'; }
Изход:
Здравей свят!!
# 2) Грешна дефиниция (подписите не съвпадат) на използваните обекти
Още една причина за грешка „недефинирана препратка“ е, когато посочваме грешни дефиниции. Използваме всеки обект в нашата програма и дефиницията му е нещо различно.
Помислете за следната програма на C ++. Тук се обадихме на func1 (). Неговият прототип е int func1 (). Но дефиницията му не съвпада с прототипа му. Както виждаме, дефиницията на функцията съдържа параметър за функцията.
По този начин, когато програмата е компилирана, компилацията е успешна поради съвпадението на прототипа и функцията. Но когато линкерът се опитва да свърже извикването на функцията с нейната дефиниция, той открива проблема и издава грешката като „недефинирана препратка“.
#include using namespace std; int func1(); int main() { func1(); } int func1(int n){ cout<<'hello, world!!'; }
Изход:
По този начин, за да предотвратим подобни грешки, ние просто проверяваме дали дефинициите и използването на всички обекти съвпадат в нашата програма.
# 3) Обектните файлове не са свързани правилно
Този проблем може да доведе и до грешка „недефинирана препратка“. Тук може да имаме повече от един изходен файл и да ги компилираме независимо. Когато това се направи, обектите не са свързани правилно и това води до „недефинирана препратка“.
Обмислете следните две програми на C ++. В първия файл използваме функцията “print ()”, която е дефинирана във втория файл. Когато компилираме тези файлове поотделно, първият файл дава „недефинирана референция“ за функцията за печат, докато вторият файл дава „недефинирана референция“ за основната функция.
int print(); int main() { print(); }
Изход:
int print() { return 42; }
Изход:
Начинът за разрешаване на тази грешка е да се компилират и двата файла едновременно ( Например, с помощта на g ++).
Освен вече обсъдените причини, „неопределена препратка“ може да възникне и поради следните причини.
# 4) Грешен тип проект
Когато посочим грешни типове проекти в C ++ IDE като визуалното студио и се опитаме да направим неща, които проектът не очаква, тогава получаваме „недефинирана референция“.
# 5) Няма библиотека
Ако програмист не е посочил правилно пътя на библиотеката или е напълно забравил да го посочи, тогава получаваме „недефинирана препратка“ за всички препратки, които програмата използва от библиотеката.
# 6) Зависимите файлове не се компилират
Програмистът трябва да гарантира, че предварително компилираме всички зависимости на проекта, така че когато компилираме проекта, компилаторът да намери всички зависимости и да ги компилира успешно. Ако някоя от зависимостите липсва, тогава компилаторът дава „недефинирана препратка“.
Освен причините, обсъдени по-горе, грешката „недефинирана препратка“ може да възникне в много други ситуации. Изводът е, че програмистът е объркал нещата и за да предотврати тази грешка, те трябва да бъдат коригирани.
най-добрият начин за изтегляне на аудио от youtube
Грешка в сегментирането (изхвърлено ядро)
Грешката „грешка в сегментирането (изхвърлено ядро)“ е грешка, която показва повреда на паметта. Обикновено това се случва, когато се опитваме да получим достъп до памет, която не принадлежи към разглежданата програма.
Ето някои от причините, които причиняват грешка при грешка в сегментирането.
# 1) Промяна на постоянния низ
Помислете за следната програма, в която сме декларирали константа на низ. След това се опитваме да модифицираме този постоянен низ. Когато програмата се изпълни, получаваме грешката, показана в изхода.
#include int main() { char *str; //constant string str = 'STH'; //modifying constant string *(str+1) = 'c'; return 0; }
Изход:
# 2) Показалец за пренасочване
Указателят трябва да сочи към валидно местоположение в паметта, преди да го разграничим. В програмата по-долу виждаме, че указателят сочи към NULL, което означава, че мястото на паметта, към което сочи, е 0, т.е.невалидно.
Следователно, когато го преориентираме в следващия ред, всъщност се опитваме да осъществим достъп до неизвестното му местоположение в паметта. Това наистина води до грешка в сегментирането.
#include using namespace std; int main() { int* ptr = NULL; //here we are accessing unknown memory location *ptr = 1; cout << *ptr; return 0; }
Изход:
грешка в сегментацията
Следващата програма показва подобен случай. В тази програма показалецът също не сочи към валидни данни. Неинициализиран указател е толкова добър, колкото NULL и следователно той сочи към неизвестно местоположение на паметта. По този начин, когато се опитваме да го разграничим, това води до грешка в сегментирането.
#include using namespace std; int main() { int *p; cout<<*p; return 0; }
Изход:
грешка в сегментацията
За да предотвратим подобни грешки, трябва да гарантираме, че нашите променливи на указателя в програмата винаги сочат към валидни места в паметта.
# 3) Препълване на стека
Когато имаме рекурсивни повиквания в нашата програма, те изяждат цялата памет в стека и причиняват препълване на стека. В такива случаи получаваме грешка в сегментирането, тъй като изчерпването на паметта на стека също е вид повреда на паметта.
Помислете за програмата по-долу, където рекурсивно изчисляваме факториал на число. Имайте предвид, че нашето основно състояние тества дали числото е 0 и след това връща 1. Тази програма работи перфектно за положителни числа.
Но какво се случва, когато всъщност предадем отрицателно число на факториална функция? Е, тъй като основното условие не е дадено за отрицателните числа, функцията не знае къде да спре и по този начин води до препълване на стека.
Това е показано в изхода по-долу, който дава грешка в сегментирането.
#include using namespace std; int factorial(int n) { if(n == 0) { return 1; } return factorial(n-1) * n; } int main() { cout< Изход:
Грешка в сегментирането (изхвърлено ядро)
Сега, за да поправим тази грешка, леко променяме основното състояние и също така посочваме случая за отрицателни числа, както е показано по-долу.
#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:'< Изход:
Факторни резултати: 1
Сега виждаме, че е отстранена грешката при сегментирането и програмата работи добре.
Неразрешен външен символ
Неразрешеният външен символ е грешка на свързващото устройство, което показва, че не може да намери символа или неговата референция по време на процеса на свързване. Грешката е подобна на „недефинирана препратка“ и се издава взаимозаменяемо.
По-долу сме посочили два случая, в които може да възникне тази грешка.
# 1) Когато отнасяме структурна променлива в програмата, която съдържа статичен член.
#include struct C { static int s; }; // int C::s; // Uncomment the following line to fix the error. int main() { C c; C::s = 1; }
Изход:
В горната програма структура C има статичен член s, който не е достъпен за външните програми. Така че, когато се опитваме да му присвоим стойност в основната функция, линкерът не намира символа и може да доведе до „неразрешен външен символ“ или „недефинирана препратка“.
html интервю въпроси и отговори pdf
Начинът за коригиране на тази грешка е изрично да обхване променливата, използвайки ‘::’ извън основната, преди да я използва.
# 2) Когато имаме препратки към външни променливи в изходния файл и не сме свързали файловете, които дефинират тези външни променливи.
Този случай е показан по-долу:
#include #include using namespace std; extern int i; extern void g(); void f() { i++; g(); } int main() {}
Изход:
Като цяло, в случай на „неразрешен външен символ“, компилираният код за всеки обект като функция не успява да намери символ, към който прави препратка, може би защото този символ не е дефиниран в обектните файлове или в някоя от библиотеките посочени на линкера.
Заключение
В този урок обсъдихме някои основни грешки в C ++, които са критични и могат да повлияят на програмния поток и дори могат да доведат до срив на приложение. Подробно разгледахме всичко за грешка в сегментирането, неразрешен външен символ и недефинирана препратка.
Въпреки че тези грешки могат да възникнат по всяко време, от причините, които обсъдихме, знаем, че можем лесно да ги предотвратим, като внимателно разработим нашата програма.
=> Прочетете серията Easy C ++ Training.
Препоръчително четене