C++ programmeerimise levinumad vead ja kuidas neid parandada
C++ programmeerimine on üks võimsamaid ja paindlikumaid programmeerimiskeeli. Tänu oma võimele toetada protseduurilist, objektorienteeritud ja üldist programmeerimist on C++ laialdaselt kasutusel väga erinevates rakendustes, alates operatsioonisüsteemidest kuni suure jõudlusega mängurakendusteni. Nagu iga programmeerimiskeel, on ka C++-l mitmeid levinud vigu, millega nii uued kui ka kogenud arendajad sageli kokku puutuvad. See artikkel käsitleb mõningaid levinud vigu C++ programmeerimisel ja annab juhiseid nende parandamiseks.
1. Initsialiseerimata pointerite kasutamine
Viga:
Initsialiseerimata pointer võib osutada tundmatule mälukohale, põhjustades ootamatut käitumist või programmi krahhi. Selle vea näide on järgmine:
„cpp
int ptr; // ptr pole initsialiseeritud
ptr = 10; // Viga: pointer pole initsialiseeritud
""
Kuidas parandada:
Enne kasutamist initsialiseeri pointer. Saad selle initsialiseerida käsuga `nullptr` või kehtiva mäluaadressiga.
„cpp
int ptr = nullptr; // Initsialiseeri nullptr-iga
siseväärtus = 10;
ptr = &väärtus;
ptr = 20; // Nüüd turvaline
""
2. Mäluhalduse vead (mäluleke)
Viga:
Mäluleke tekib siis, kui eraldatud mälu ei vabastata uuesti. See võib põhjustada rakenduse poolt aja jooksul üha suurema mälukasutuse, mis lõpuks viib mälu nappuseni.
„cpp
int punktiarv = uus int[10];
// Unusta eraldatud mälu kustutada
""
Kuidas parandada:
Vabastage alati eraldatud mälu käsuga `delete` või `delete[]`, olenevalt sellest, mille abil seda eraldati.
„cpp
int punktiarv = uus int[10];
// Mälukasutus…
delete[] ptr; // Vabasta eraldatud mälu
""
Mälu haldamise lihtsustamiseks kasutage nutikate pointeriteeki (näiteks `std::unique_ptr` või `std::shared_ptr`).
„cpp
sisaldama
std::unique_ptr ptr(uus int[10]);
// Mälu vabastatakse automaatselt, kui ptr väljub ulatusest
""
3. Viidete kasutamise vead
Viga:
Viite või pointeri tagastamine lokaalsele muutujale, mis on ulatusest väljas, võib põhjustada ootamatut käitumist.
„cpp
int& getReference() {
siseväärtus = 10;
return value; // Viga: tagastatakse viide lokaalsele muutujale
}
""
Kuidas parandada:
Väldi viidete tagastamist lokaalsetele muutujatele. Selle asemel kasuta staatilisi muutujaid või veel parem, tagasta väärtusi või kaalu objektide kasutamist.
„cpp
int getValue() {
siseväärtus = 10;
tagastusväärtus; // Turvalisem
}
""
4. Ignoreeri kompilaatori veateateid ja hoiatusi
Viga:
Programmeerijad ignoreerivad sageli kompilaatori väljastatud veateateid ja hoiatusi, isegi kui need teated annavad olulist teavet võimalike vigade kohta.
Kuidas parandada:
Kontrolli alati kompilaatori genereeritud veateateid ja hoiatusi ning püüa neist aru saada. Puhtuma koodi tagamiseks luba kõrgetasemelised hoiatused.
Näiteks GCC-s kasutage rohkemate hoiatuste genereerimiseks lippu `-Wall`.
""bash
g++ -Wall -o programm main.cpp
""
5. Operaatori ülekoormuse viga
Viga:
Operaatori vale ülekoormamine võib põhjustada ootamatut käitumist või käitusaja vigu.
„cpp
class MyClass {
avalik:
int-andmed;
MinuKlassi operaator+ (const MinuKlass& muu) {
return data + other.data; // Viga: peaks tagastama MyClassi
}
};
""
Kuidas parandada:
Veenduge, et ülekoormatud operaator tagastaks sobiva tüübi ja säilitaks klassi invariantsid.
„cpp
class MyClass {
avalik:
int-andmed;
MinuKlassi operaator+ (const MinuKlass& muu) {
MinuKlassi tulemus;
tulemus.andmed = andmed + muud.andmed;
return result; // Tagastab objekti klassist MyClass
}
};
""
6. Makrode väärkasutamine
Viga:
Makrosid kasutatakse mõnikord liigselt või valesti, mis võib põhjustada vigu, mida on käitusajal raske tuvastada.
„cpp
defineeri RUUT(x) xx
int tulemus = SQUARE(5 + 1); // Viga: tulemus on 5 + 1 5 + 1
""
Kuidas parandada:
Tüübiturvalisuse ja kontrolli parandamiseks asenda makrod konstantsete avaldiste või mallidega.
„cpp
šabloon
T ruut(T x) {
tagasta xx;
}
int tulemus = ruut(5 + 1); // Ohutu kasutada
""
7. C-stiilis funktsioonide väärkasutamine
Viga:
Kasutades C-stiilis funktsioone nagu `strcpy` või `sprintf`, mis on puhvri ületäitumise suhtes haavatavad.
„cpp
char src[] = "Tere, maailm!";
char siht[5];
strcpy(dest, src); // Viga: puhvri ületäitumine
""
Kuidas parandada:
Kasuta turvalisemaid C++ funktsioone nagu `std::string` või `std::vector`.
„cpp
sisaldama
std::string src = “Tere, maailm!”;
std::string sihtkoht = allikas;
""
8. Vea tuvastamise ignoreerimine
Viga:
Ignoreeri veakontrolli I/O-operatsioonide või -funktsioonide puhul, mis võivad ebaõnnestuda.
„cpp
std::ifstream fail(“andmed.txt”);
// Viga: ei kontrollitud, kas faili avamine õnnestus
""
Kuidas parandada:
Kontrollige alati, kas toiming oli edukas, ja käsitlege vigu vastavalt.
„cpp
std::ifstream fail(“andmed.txt”);
kui (!fail) {
std::cerr << “Faili avamine ebaõnnestus” << std::endl;
1 tagasi;
}
""
9. Suboptimaalne tsükli rakendamine
Viga:
Suboptimaalsete tsüklite kasutamine võib programmi jõudlust vähendada.
„cpp
for (int i = 0; i < vec.size(); i++) {
// Protsess vec[i]-ga
// Viga: size() kutsutakse välja igal iteratsioonil
}
""
Kuidas parandada:
Optimeerige tsükleid, vähendades korduvaid funktsioonikõnesid.
„cpp
for (std::size_t i = 0, n = vec.size(); i < n; i++) {
// Protsess vec[i]-ga
}
""
Edasiseks optimeerimiseks kasutage ära ka STL-algoritme, näiteks `std::for_each`.
„cpp
sisaldama
std::for_each(vec.begin(), vec.end(), [](int &väärtus) {
// Protsess väärtusega
});
""
10. Viga lõimede käsitlemisel
Viga:
Lõimede vale käsitlemine võib põhjustada võidujooksu või ummikseisu.
„cpp
include void run() {
// Viga: Võib esineda võidujooksutingimus
}
std::thread t1(käivita);
std::thread t2(käivita);
""
Kuidas parandada:
Võidujooksu tingimuste ja ummikseisude vältimiseks kasutage sünkroniseerimisprimitiive, näiteks mutexe.
„cpp
kaasata kaasata
std::mutex mtx;
tühine jooks() {
std::lock_guard lukk(mtx);
// Protsess, mis on võidujooksutingimuste eest kaitstud
}
std::thread t1(käivita);
std::thread t2(käivita);
t1.liitu();
t2.liitu();
""
Järeldus
C++ on võimas ja paindlik programmeerimiskeel, kuid see on altid ka levinud vigadele, eriti mälu ja pointeri haldamisega seotud vigadele. Nende vigade mõistmise ja parandamise oskuse abil saate arendada usaldusväärsemaid ja tõhusamaid rakendusi. Pidage alati meeles, et pöörake tähelepanu kompilaatori sõnumitele, kasutage kaasaegseid tööriistu, mis aitavad teil kirjutada turvalist koodi , ja lihvige pidevalt oma oskusi C++ programmeerimise parimate tavade mõistmisel ja rakendamisel.