Biežāk pieļautās kļūdas C++ programmēšanā un to labošana

Biežāk pieļautās kļūdas C++ programmēšanā un to labošana

C++ programmēšana ir viena no jaudīgākajām un elastīgākajām programmēšanas valodām. Pateicoties spējai atbalstīt procedurālo, objektorientēto un vispārīgo programmēšanu, C++ tiek plaši izmantota dažādās lietojumprogrammās, sākot no operētājsistēmām līdz augstas veiktspējas spēļu lietojumprogrammām. Tomēr, tāpat kā jebkurai programmēšanas valodai, arī C++ ir vairākas izplatītas kļūdas, ar kurām bieži saskaras gan jauni, gan pieredzējuši izstrādātāji. Šajā rakstā tiks apspriestas dažas izplatītas kļūdas C++ programmēšanā un sniegti norādījumi par to labošanu.

1. Neinicializētu rādītāju izmantošana

Kļūda:
Neinicializēts rādītājs var norādīt uz nezināmu atmiņas atrašanās vietu, izraisot negaidītu darbību vai programmas avāriju. Šīs kļūdas piemērs ir šāds:

“Cpp
int ptr; // ptr nav inicializēts
ptr = 10; // Kļūda: rādītājs nav inicializēts
“

Kā labot:
Pirms lietošanas inicializējiet rādītāju. To var inicializēt ar `nullptr` vai ar derīgu atmiņas adresi.

“Cpp
int ptr = nullptr; // Inicializēt ar nullptr
int vērtība = 10;
ptr = &vērtība;
ptr = 20; // Tagad droši
“

2. Kļūdas atmiņas pārvaldībā (atmiņas noplūde)

Kļūda:
Atmiņas noplūde rodas, ja piešķirtā atmiņa netiek atkārtoti atbrīvota. Tas var izraisīt to, ka lietojumprogramma laika gaitā izmanto arvien vairāk atmiņas, galu galā izraisot atmiņas trūkumu.

“Cpp
int ptr = new int[10];
// Aizmirstiet izdzēst piešķirto atmiņu
“

Kā labot:
Vienmēr pārliecinieties, ka atbrīvotā atmiņa ir atbrīvota, izmantojot funkciju `delete` vai `delete[]` atkarībā no tā, kas tika izmantots tās piešķiršanai.

“Cpp
int ptr = new int[10];
// Atmiņas izmantošana…
dzēst[] ptr; // Atbrīvot piešķirto atmiņu
“

Izmantojiet viedās norādes bibliotēku (piemēram, `std::unique_ptr` vai `std::shared_ptr`), lai atvieglotu atmiņas pārvaldību.

“Cpp
ietvert

std::unique_ptr ptr(jauns int[10]);
// Atmiņa tiks automātiski atbrīvota, kad ptr izies no darbības jomas
“

3. Kļūdas atsauču lietošanā

Kļūda:
Atsauces vai rādītāja atgriešana lokālam mainīgajam, kas ir ārpus darbības jomas, var izraisīt negaidītu darbību.

“Cpp
int& getReference() {
int vērtība = 10;
atgriešanas vērtība; // Kļūda: atgriež atsauci uz lokālo mainīgo
}
“

Kā labot:
Izvairieties no atsauču atgriešanas uz lokāliem mainīgajiem. Tā vietā izmantojiet statiskos mainīgos vai, vēl labāk, atgrieziet vērtības vai apsveriet objektu izmantošanu.

“Cpp
int getValue() {
int vērtība = 10;
atgriešanas vērtība; // Drošāk
}
“

4. Ignorējiet kompilatora kļūdu ziņojumus un brīdinājumus

Kļūda:
Programmētāji bieži ignorē kompilatora izdotos kļūdu ziņojumus un brīdinājumus, pat ja šie ziņojumi sniedz svarīgu informāciju par iespējamām kļūdām.

Kā labot:
Vienmēr pārbaudiet un izprotiet kompilatora ģenerētos kļūdu ziņojumus un brīdinājumus. Iespējojiet augsta līmeņa brīdinājumus, lai nodrošinātu tīrāku kodu.

Piemēram, GCC vidē izmantojiet karodziņu `-Wall`, lai ģenerētu vairāk brīdinājumu.

“`bash
g++ -Wall -o programma main.cpp
“

5. Operatora pārslodzes kļūda

Kļūda:
Nepareiza operatora pārslodze var izraisīt negaidītu darbību vai izpildes laika kļūdas.

“Cpp
class MyClass {
publiski:
int dati;
ManasKlases operators+ (const ManaKlase& cits) {
return data + other.data; // Kļūda: vajadzētu atgriezt ManuKlassi
}
};
“

Kā labot:
Pārliecinieties, vai pārslogotais operators atgriež atbilstošo tipu un saglabā klases invariantus.

“Cpp
class MyClass {
publiski:
int dati;
ManasKlases operators+ (const ManaKlase& cits) {
MyClass rezultāts;
rezultāts.dati = dati + citi.dati;
return result; // Atgriež objektu no MyClass
}
};
“

6. Makro ļaunprātīga izmantošana

Kļūda:
Makro dažreiz tiek izmantoti pārmērīgi vai nepareizi, kas var izraisīt kļūdas, kuras ir grūti atklāt izpildes laikā.

“Cpp
definēt KVADRĀTU(x) xx

int rezultāts = SQUARE(5 + 1); // Kļūda: rezultāts ir 5 + 1 5 + 1
“

Kā labot:
Lai uzlabotu tipu drošību un kontroli, aizstājiet makro ar konstantām izteiksmēm vai veidnēm.

“Cpp
veidne
T kvadrāts(T x) {
atgriezties xx;
}

int rezultāts = kvadrāts(5 + 1); // Droši lietojams
“

7. C stila funkciju nepareiza izmantošana

Kļūda:
Izmantojot C stila funkcijas, piemēram, `strcpy` vai `sprintf`, kas ir neaizsargātas pret bufera pārpildi.

“Cpp
char src[] = "Sveika, pasaule!";
rakstzīmju galamērķis[5];
strcpy(dest, src); // Kļūda: bufera pārpilde
“

Kā labot:
Izmantojiet drošākas C++ funkcijas, piemēram, `std::string` vai `std::vector`.

“Cpp
ietvert
std::string src = “Sveika, pasaule!”;
std::string galamērķis = src;
“

8. Kļūdu noteikšanas ignorēšana

Kļūda:
Ignorējiet kļūdu pārbaudi I/O operācijās vai funkcijās, kas var neizdoties.

“Cpp
std::ifstream fails(“dati.txt”);
// Kļūda: netika pārbaudīts, vai fails tika veiksmīgi atvērts
“

Kā labot:
Vienmēr pārbaudiet, vai darbība bija veiksmīga, un atbilstoši rīkojieties, ja rodas kļūdas.

“Cpp
std::ifstream fails(“dati.txt”);
ja (!fails) {
std::cerr << “Neizdevās atvērt failu” << std::endl;
1 atgriezties;
}
“

9. Suboptimāla cikla ieviešana

Kļūda:
Izmantojot suboptimālas cilpas, var samazināties programmas veiktspēja.

“Cpp
for (int i = 0; i < vec.size(); i++) {
// Apstrādāt ar vec[i]
// Kļūda: size() izsaukta katrā iterācijā
}
“

Kā labot:
Optimizējiet ciklus, samazinot atkārtotus funkciju izsaukumus.

“Cpp
for (std::size_t i = 0, n = vec.size(); i < n; i++) {
// Apstrādāt ar vec[i]
}
“

Izmantojiet arī STL algoritmus, piemēram, `std::for_each`, lai veiktu turpmāku optimizāciju.

“Cpp
ietvert
std::for_each(vec.begin(), vec.end(), [](int &value) { }
// Process ar vērtību
});
“

10. Kļūda pavedienu apstrādē

Kļūda:
Nepareiza pavedienu apstrāde var izraisīt sacensību apstākļus vai strupceļus.

“Cpp
iekļaut tukšu palaišanu() {
// Kļūda: Var rasties sacensību nosacījums
}

std::thread t1(palaist);
std::thread t2(palaist);
“

Kā labot:
Izmantojiet sinhronizācijas primitīvus, piemēram, savstarpējas savienošanas (mutexes), lai novērstu sacensību apstākļus un strupceļus.

“Cpp
iekļaut iekļaut

std::mutex mtx;

tukša palaišana() {
std::lock_guard slēdzene(mtx);
// Process, kas ir drošs no sacensību apstākļiem
}

std::thread t1(palaist);
std::thread t2(palaist);

t1.pievienošanās();
t2.pievienošanās();
“

Secinājums

C++ ir jaudīga un elastīga programmēšanas valoda, taču tai ir arī tendence uz bieži sastopamām kļūdām, īpaši saistībā ar atmiņas un rādītāja pārvaldību. Izprotot šīs kļūdas un zinot, kā tās novērst, jūs varat izstrādāt uzticamākas un efektīvākas lietojumprogrammas. Atcerieties vienmēr pievērst uzmanību kompilatora ziņojumiem, izmantot modernus rīkus, kas palīdz rakstīt drošu kodu , un pastāvīgi pilnveidot savas prasmes C++ programmēšanas labākās prakses izpratnē un pielietošanā.

Atstājiet komentāru