C++ програмчлалын нийтлэг алдаанууд болон тэдгээрийг хэрхэн засах вэ
C++ програмчлал нь хамгийн хүчирхэг бөгөөд уян хатан програмчлалын хэлнүүдийн нэг юм. Процедурын, объект хандалтат болон ерөнхий програмчлалыг дэмжих чадвартай тул C++ нь үйлдлийн системээс эхлээд өндөр гүйцэтгэлтэй тоглоомын програмууд хүртэл олон төрлийн програмуудад өргөн хэрэглэгддэг. Гэсэн хэдий ч бусад програмчлалын хэлний нэгэн адил C++ нь шинэ болон туршлагатай хөгжүүлэгчид байнга тулгардаг хэд хэдэн нийтлэг алдаатай байдаг. Энэ нийтлэлд C++ програмчлалын зарим нийтлэг алдаануудын талаар хэлэлцэж, тэдгээрийг хэрхэн засах талаар зааварчилгаа өгөх болно.
1. Анхлан тохируулаагүй заагч ашиглах
Алдаа:
Эхлүүлээгүй заагч нь тодорхойгүй санах ойн байршил руу зааж, гэнэтийн үйлдэл эсвэл програмын гацалт үүсгэж болзошгүй. Энэ алдааны жишээг дараах байдлаар харуулав.
“`cpp
int ptr; // ptr нь эхлүүлэгдээгүй байна
ptr = 10; // Алдаа: заагчийг эхлүүлээгүй байна
""
Засах арга:
Ашиглахаасаа өмнө заагчийг эхлүүлнэ үү. Та үүнийг `nullptr` эсвэл хүчинтэй санах ойн хаягаар эхлүүлж болно.
“`cpp
int ptr = nullptr; // nullptr ашиглан эхлүүлнэ үү
int утга = 10;
ptr = &утга;
ptr = 20; // Одоо аюулгүй
""
2. Санах ойн менежментийн алдаа (Санах ойн алдагдал)
Алдаа:
Хуваарилагдсан санах ойг дахин суллахгүй үед санах ойн алдагдал үүсдэг. Энэ нь програм цаг хугацааны явцад улам их санах ой ашиглахад хүргэж, улмаар санах ойн хомсдолд хүргэж болзошгүй.
“`cpp
int ptr = шинэ int[10];
// Хуваарилагдсан санах ойг устгахаа мартаарай
""
Засах арга:
Хуваарилагдсан санах ойг юугаар хуваарилснаас хамааран `delete` эсвэл `delete[]` командыг ашиглан үргэлж чөлөөтэй хуваарилж байгаарай.
“`cpp
int ptr = шинэ int[10];
// Санах ойн хэрэглээ…
устгах[] ptr; // Чөлөөт хуваарилагдсан санах ой
""
Санах ойн менежментийг хялбар болгохын тулд ухаалаг заагч санг (жишээ нь `std::unique_ptr` эсвэл `std::shared_ptr`) ашиглаарай.
“`cpp
оруулах
std::unique_ptr
// ptr нь хүрээнээс гарахад санах ой автоматаар суллагдана
""
3. Лавлагаа ашиглахад гарсан алдаанууд
Алдаа:
Хамрах хүрээнээс гарсан орон нутгийн хувьсагч руу лавлагаа эсвэл заагч буцаах нь гэнэтийн зан төлөвт хүргэж болзошгүй.
“`cpp
int& getReference() {
int утга = 10;
буцах утга; // Алдаа: орон нутгийн хувьсагчийн лавлагааг буцаах
}
""
Засах арга:
Орон нутгийн хувьсагч руу лавлагаа буцаахаас зайлсхий. Үүний оронд статик хувьсагч ашиглах, эсвэл бүр илүү сайн нь утгуудыг буцаах, эсвэл объектуудыг ашиглах талаар бодож үзээрэй.
“`cpp
int getValue() {
int утга = 10;
буцах утга; // Илүү аюулгүй
}
""
4. Хөрвүүлэгчийн алдааны мессеж болон анхааруулгыг үл тоомсорлох
Алдаа:
Программистууд хөрвүүлэгчийн гаргасан алдааны мэдэгдэл болон анхааруулгыг үл тоомсорлодог ч эдгээр мессежүүд нь болзошгүй алдааны талаар чухал мэдээлэл өгдөг.
Засах арга:
Хөрвүүлэгчийн үүсгэсэн алдааны мэдэгдэл болон анхааруулгыг үргэлж шалгаж, ойлгоорой. Илүү цэвэр кодыг хангахын тулд өндөр түвшний анхааруулгыг идэвхжүүл.
Жишээлбэл, GCC-д илүү олон анхааруулга үүсгэхийн тулд `-Wall` тугийг ашиглана уу.
"`баш
g++ -Wall -o програм main.cpp
""
5. Операторын хэт ачааллын алдаа
Алдаа:
Операторын буруу хэт ачаалал нь гэнэтийн үйлдэл эсвэл ажиллах үеийн алдаа үүсгэж болзошгүй.
“`cpp
МинийАнгилал {
олон нийтийн:
int өгөгдөл;
MyClass оператор+ (const MyClass& бусад) {
өгөгдөл + other.data буцаах; // Алдаа: MyClass буцаах ёстой
}
};
""
Засах арга:
Хэт ачаалагдсан оператор нь тохирох төрлийг буцаан өгч, ангийн инвариантуудыг хадгалж байгаа эсэхийг шалгаарай.
“`cpp
МинийАнгилал {
олон нийтийн:
int өгөгдөл;
MyClass оператор+ (const MyClass& бусад) {
MyClass үр дүн;
үр дүн.өгөгдөл = өгөгдөл + бусад.өгөгдөл;
үр дүн буцаах; // MyClass-аас объект буцаана
}
};
""
6. Макрог буруу ашиглах
Алдаа:
Макрог заримдаа хэт их эсвэл буруу ашигладаг бөгөөд энэ нь ажиллах явцад илрүүлэхэд хэцүү алдаа гаргахад хүргэдэг.
“`cpp
SQUARE(x) xx-г тодорхойлно уу
int result = SQUARE(5 + 1); // Алдаа: үр дүн нь 5 + 1 5 + 1 байна
""
Засах арга:
Илүү сайн төрлийн аюулгүй байдал болон хяналтыг хангахын тулд макрог тогтмол илэрхийллүүд эсвэл загваруудаар солино уу.
“`cpp
загвар
Т квадрат(T x) {
буцах xx;
}
int result = square(5 + 1); // Ашиглахад аюулгүй
""
7. C хэлбэрийн функцуудыг буруу ашиглах
Алдаа:
Буферийн халилтад өртөмтгий `strcpy` эсвэл `sprintf` гэх мэт C хэлбэрийн функцуудыг ашиглах.
“`cpp
char src[] = "Сайн уу, Дэлхий!";
char dest[5];
strcpy(dest, src); // Алдаа: буфер халих
""
Засах арга:
`std::string` эсвэл `std::vector` гэх мэт илүү аюулгүй C++ функцуудыг ашиглаарай.
“`cpp
оруулах
std::string src = “Сайн уу, Дэлхий!”;
std::string dest = src;
""
8. Алдаа илрүүлэлтийг үл тоомсорлох
Алдаа:
Амжилтгүй болж болзошгүй I/O үйлдэл эсвэл функцүүдийн алдаа шалгахыг үл тоомсорло.
“`cpp
std::ifstream файл(“өгөгдөл.txt”);
// Алдаа: файл амжилттай нээгдсэн эсэхийг шалгаагүй
""
Засах арга:
Үйлдэл амжилттай болсон эсэхийг үргэлж шалгаж, алдааг зохих ёсоор нь шийдвэрлээрэй.
“`cpp
std::ifstream файл(“өгөгдөл.txt”);
хэрэв (!файл) {
std::cerr << "Файлыг нээж чадсангүй" << std::endl; return 1; } ``` 9. Оновчтой бус давталтын хэрэгжилтийн алдаа: Оновчтой бус давталт ашиглах нь програмын гүйцэтгэлийг бууруулж болзошгүй. ```cpp for (int i = 0; i < vec.size(); i++) { // vec[i]-тэй процесс // Алдаа: size() нь давталт бүрт дуудагддаг } ``` Засвар: Давтагдсан функцийн дуудлагыг багасгах замаар давталтыг оновчтой болгох. ```cpp for (std::size_t i = 0, n = vec.size(); i < n; i++) { // vec[i]-тэй процесс } ``` Цаашдын оновчлолын хувьд `std::for_each` гэх мэт STL алгоритмуудыг ашиглах. ```cpp include
std::for_each(vec.begin(), vec.end(), [](int & утга) {
// Утгатай процесс
});
""
10. Урсгалтай ажиллахад алдаа гарлаа
Алдаа:
Утаснуудыг буруу барьснаар уралдааны нөхцөл байдал эсвэл гацаанд хүргэж болзошгүй.
“`cpp
оруулах
// Алдаа: Уралдааны нөхцөл байдал үүсч болзошгүй
}
std::thread t1(run);
std::thread t2(run);
""
Засах арга:
Уралдааны нөхцөл байдал болон мухардлаас урьдчилан сэргийлэхийн тулд мутекс гэх мэт синхрончлолын командуудыг ашиглаарай.
“`cpp
оруулах
std::mutex mtx;
хүчингүй гүйлт() {
std::lock_guard
// Уралдааны нөхцөл байдлаас аюулгүй үйл явц
}
std::thread t1(run);
std::thread t2(run);
t1.join();
t2.join();
""
Дүгнэлт
C++ бол хүчирхэг бөгөөд уян хатан програмчлалын хэл боловч санах ой болон заагчийн удирдлагатай холбоотой нийтлэг алдаа гарах хандлагатай байдаг. Эдгээр алдааг ойлгож, тэдгээрийг хэрхэн засахаа мэдсэнээр та илүү найдвартай, үр ашигтай програмуудыг хөгжүүлж чадна. Хөрвүүлэгчийн мессежүүдэд үргэлж анхаарал хандуулж, аюулгүй код бичихэд тусалдаг орчин үеийн хэрэгслүүдийг ашиглаж, C++ програмчлалын шилдэг туршлагыг ойлгож, хэрэгжүүлэх ур чадвараа байнга сайжруулж байгаарай.