Dažniausios C++ programavimo klaidos ir kaip jas ištaisyti

Dažniausios C++ programavimo klaidos ir kaip jas ištaisyti

C++ programavimas yra viena galingiausių ir lanksčiausių programavimo kalbų. Dėl savo gebėjimo palaikyti procedūrinį, objektinį ir bendrąjį programavimą, C++ yra plačiai naudojama įvairiose programose – nuo ​​operacinių sistemų iki didelio našumo žaidimų programų. Tačiau, kaip ir bet kuri programavimo kalba, C++ taip pat turi keletą dažnų klaidų, su kuriomis dažnai susiduria tiek pradedantieji, tiek patyrę kūrėjai. Šiame straipsnyje bus aptartos kelios dažnos C++ programavimo klaidos ir pateikti patarimai, kaip jas ištaisyti.

1. Neinicializuotų rodyklių naudojimas

Klaida:
Neinicializuotas rodyklė gali nurodyti į nežinomą atminties vietą ir sukelti netikėtą veikimą arba programos gedimą. Šios klaidos pavyzdys pateiktas toliau:

„cpp
int ptr; // ptr nėra inicializuotas
ptr = 10; // Klaida: rodyklė neinicializuota
„“

Kaip ištaisyti:
Prieš naudojimą inicijuokite rodyklę. Galite ją inicijuoti naudodami `nullptr` arba galiojančiu atminties adresu.

„cpp
int ptr = nullptr; // Inicializuoti su nullptr
int reikšmė = 10;
ptr = &reikšmė;
ptr = 20; // Dabar saugu
„“

2. Atminties valdymo klaidos (atminties nutekėjimas)

Klaida:
Atminties nutekėjimas įvyksta, kai paskirta atmintis nėra iš naujo atlaisvinama. Dėl to programa laikui bėgant gali naudoti vis daugiau atminties, o tai galiausiai gali sukelti atminties trūkumą.

„cpp
sveikasis_skaitmuo = naujas sveikasis_skaitmuo[10];
// Pamirškite ištrinti paskirtą atmintį
„“

Kaip ištaisyti:
Visada atlaisvinkite paskirtą atmintį naudodami komandą „delete“ arba „delete[]“, priklausomai nuo to, kas buvo panaudota jai paskirstyti.

„cpp
sveikasis_skaitmuo = naujas sveikasis_skaitmuo[10];
// Atminties naudojimas…
delete[] ptr; // Atlaisvinti skirtą atmintį
„“

Norėdami palengvinti atminties valdymą, naudokite išmaniųjų rodyklių biblioteką (pvz., `std::unique_ptr` arba `std::shared_ptr`).

„cpp
įtraukti

std::unique_ptr ptr(naujas sveikasis_skaitmuo[10]);
// Atmintis bus automatiškai atlaisvinta, kai ptr išeis iš apimties
„“

3. Nuorodų naudojimo klaidos

Klaida:
Nuorodos arba rodyklės grąžinimas į vietinį kintamąjį, kuris nebėra taikomas, gali sukelti netikėtą elgesį.

„cpp
int& gautiNuoroda() {
int reikšmė = 10;
grąžina reikšmę; // Klaida: grąžinama nuoroda į vietinį kintamąjį
}
„“

Kaip ištaisyti:
Venkite grąžinti nuorodas į vietinius kintamuosius. Vietoj to naudokite statinius kintamuosius arba, dar geriau, grąžinkite reikšmes arba apsvarstykite galimybę naudoti objektus.

„cpp
int gautiReikšmę() {
int reikšmė = 10;
grąžinamoji vertė; // Saugesnis
}
„“

4. Nepaisykite kompiliatoriaus klaidų pranešimų ir įspėjimų

Klaida:
Programuotojai dažnai ignoruoja kompiliatoriaus pateikiamus klaidų pranešimus ir įspėjimus, net jei šie pranešimai suteikia svarbios informacijos apie galimas klaidas.

Kaip ištaisyti:
Visada patikrinkite ir supraskite kompiliatoriaus generuojamus klaidų pranešimus ir įspėjimus. Įjunkite aukšto lygio įspėjimus, kad užtikrintumėte švaresnį kodą.

Pavyzdžiui, GCC sistemoje naudokite žymę „-Wall“, kad sugeneruotumėte daugiau įspėjimų.

„bash
g++ -Wall -o programa main.cpp
„“

5. Operatoriaus perkrovos klaida

Klaida:
Neteisingas operatoriaus perkrovimas gali sukelti netikėtą veikimą arba vykdymo klaidas.

„cpp
class MyClass {
viešas:
vidiniai duomenys;
„MyClass“ operatorius+ (const MyClass& other) {
return data + other.data; // Klaida: turėtų grąžinti MyClass
}
};
„“

Kaip ištaisyti:
Įsitikinkite, kad perkrautas operatorius grąžina tinkamą tipą ir išsaugo klasės invariantus.

„cpp
class MyClass {
viešas:
vidiniai duomenys;
„MyClass“ operatorius+ (const MyClass& other) {
„MyClass“ rezultatas;
rezultatas.duomenys = duomenys + kiti.duomenys;
return result; // Grąžina objektą iš MyClass
}
};
„“

6. Makrokomandų netinkamas naudojimas

Klaida:
Makrokomandos kartais naudojamos pernelyg dažnai arba neteisingai, todėl gali atsirasti klaidų, kurias sunku aptikti vykdymo metu.

„cpp
apibrėžti SQUARE(x) xx

sveikasis rezultatas = SQUARE(5 + 1); // Klaida: rezultatas yra 5 + 1 5 + 1
„“

Kaip ištaisyti:
Makrokomandas pakeiskite pastoviomis išraiškomis arba šablonais, kad pagerintumėte tipų saugumą ir valdymą.

„cpp
šablonas
T kvadratas(T x) {
grąžinti xx;
}

sveikasis rezultatas = kvadratas(5 + 1); // Saugu naudoti
„“

7. C stiliaus funkcijų netinkamas naudojimas

Klaida:
Naudojamos C stiliaus funkcijos, tokios kaip `strcpy` arba `sprintf`, kurios yra pažeidžiamos buferio perpildymo.

„cpp
char src[] = „Sveikas, pasauli!“;
char tikslas[5];
strcpy(dest, src); // Klaida: buferio perpildymas
„“

Kaip ištaisyti:
Naudokite saugesnes C++ funkcijas, tokias kaip `std::string` arba `std::vector`.

„cpp
įtraukti
std::string src = „Sveikas, pasauli!“;
std::string dest = src;
„“

8. Klaidų aptikimo ignoravimas

Klaida:
Ignoruokite klaidų tikrinimą įvesties / išvesties operacijose arba funkcijose, kurios gali nepavykti.

„cpp
std::ifstream failas („duomenys.txt“);
// Klaida: nepatikrinta, ar failas sėkmingai atidarytas
„“

Kaip ištaisyti:
Visada patikrinkite, ar operacija buvo sėkminga, ir tinkamai ištaisykite klaidas.

„cpp
std::ifstream failas („duomenys.txt“);
jei (!failas) {
std::cerr << „Nepavyko atidaryti failo“ << std::endl;
1 grįžti;
}
„“

9. Suboptimalus ciklo įgyvendinimas

Klaida:
Naudojant neoptimalius ciklus, gali sumažėti programos našumas.

„cpp
for (int i = 0; i < vec.size(); i++) {
// Apdoroti su vec[i]
// Klaida: size() iškviečiama kiekvienoje iteracijoje
}
„“

Kaip ištaisyti:
Optimizuokite ciklus, sumažindami pasikartojančius funkcijų iškvietimus.

„cpp
for (std::size_t i = 0, n = vec.size(); i < n; i++) { }
// Apdoroti su vec[i]
}
„“

Taip pat pasinaudokite STL algoritmais, tokiais kaip `std::for_each`, kad galėtumėte toliau optimizuoti.

„cpp
įtraukti
std::for_each(vec.begin(), vec.end(), [](int ir reikšmė) {
// Procesas su reikšme
});
„“

10. Klaida gijų tvarkyme

Klaida:
Netinkamas gijų tvarkymas gali sukelti lenktynes ​​arba aklavietes.

„cpp
įtraukti void run() {
// Klaida: Gali susidaryti lenktynių sąlyga
}

std::thread t1(vykdyti);
std::thread t2(vykdyti);
„“

Kaip ištaisyti:
Naudokite sinchronizavimo primityvus, tokius kaip „mutexes“, kad išvengtumėte lenktynių sąlygų ir aklavimų.

„cpp
įtraukti įtraukti

std::mutex mtx;

tuščias vykdymas() {
std::lock_guard užraktas(mtx);
// Procesas, saugus nuo lenktynių sąlygų
}

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

t1.join();
t2.join();
„“

Išvada

C++ yra galinga ir lanksti programavimo kalba, tačiau ji taip pat linkusi į dažnas klaidas, ypač susijusias su atminties ir rodyklės valdymu. Suprasdami šias klaidas ir žinodami, kaip jas ištaisyti, galite kurti patikimesnes ir efektyvesnes programas. Nepamirškite visada atkreipti dėmesio į kompiliatoriaus pranešimus, naudoti modernius įrankius, kurie padeda rašyti saugų kodą , ir nuolat tobulinti savo įgūdžius, kaip suprasti ir taikyti geriausią C++ programavimo praktiką.

Palikite komentarą