C/C++ 程式的常見陷阱與範例 下篇

本篇 ShengYu 介紹 C/C++ 程式的常見陷阱與範例,C/C++ 寫程式時有許多常見的陷阱,以下是一些 C/C++ 常見陷阱的範例,同時也會說明如何避免與一些使用建議。

以下介紹 C/C++ 程式的常見陷阱分為,

  • 線程競爭(Thread Race Conditions)陷阱
  • 不良的記憶體管理(Poor Memory Management)陷阱
  • 硬編碼數值(Hardcoded Values)陷阱
  • 未處理的返回值(Unchecked Return Values)陷阱
  • 錯誤的類型轉換(Incorrect Type Conversions)陷阱

線程競爭(Thread Race Conditions)陷阱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <thread>

int sharedVariable = 0;

void IncrementSharedVariable() {
for (int i = 0; i < 10000; ++i) {
sharedVariable++; // 非原子操作,可能導致競爭條件
}
}

int main() {
std::thread t1(IncrementSharedVariable);
std::thread t2(IncrementSharedVariable);
t1.join();
t2.join();
std::cout << "Shared variable: " << sharedVariable << std::endl;
return 0;
}

如何避免:使用互斥鎖(Mutex)或其他同步機制來確保多線程操作共享資源的安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <thread>
#include <mutex>

int sharedVariable = 0;
std::mutex mtx;

void IncrementSharedVariable() {
for (int i = 0; i < 10000; ++i) {
std::lock_guard<std::mutex> lock(mtx); // 使用互斥鎖保護共享變數
sharedVariable++;
}
}

int main() {
std::thread t1(IncrementSharedVariable);
std::thread t2(IncrementSharedVariable);
t1.join();
t2.join();
std::cout << "Shared variable: " << sharedVariable << std::endl;
return 0;
}

不良的記憶體管理(Poor Memory Management)陷阱

1
2
int* data = new int[10];
// 忘記釋放記憶體

如何避免:使用delete[]來釋放動態分配的記憶體。

1
2
3
int* data = new int[10];
// 使用 data
delete[] data; // 釋放記憶體

硬編碼數值(Hardcoded Values)陷阱

1
2
3
int calculateArea(int length, int width) {
return length * width * 3.14159; // 使用硬編碼的數值
}

如何避免:使用常數或宏定義,或更好地命名和組織數值,以提高代碼的可讀性。

1
2
3
4
5
const double PI = 3.14159;

int calculateArea(int length, int width) {
return length * width * PI; // 使用常數代替硬編碼的數值
}

未處理的返回值(Unchecked Return Values)陷阱

1
2
FILE* file = fopen("example.txt", "r");
fread(buffer, 1, sizeof(buffer), file); // 未檢查fread的返回值

如何避免:始終檢查函數的返回值並處理錯誤情況,例如檢查fread是否成功。

1
2
3
4
5
6
7
8
9
10
FILE* file = fopen("example.txt", "r");
if (file != nullptr) {
size_t bytesRead = fread(buffer, 1, sizeof(buffer), file); // 檢查fread的返回值
if (bytesRead == 0) {
// 處理讀取錯誤
}
fclose(file);
} else {
// 處理文件打開錯誤
}

錯誤的類型轉換(Incorrect Type Conversions)陷阱

1
2
int x = 10;
char c = (char)x; // 不恰當的類型轉換

如何避免:謹慎處理類型轉換,確保不會導致數據丟失或不正確的計算結果。使用合適的轉換方法,如static_cast(C++)。

1
2
int x = 10;
char c = static_cast<char>(x); // 使用static_cast進行安全類型轉換

空指針(Null Pointers)陷阱

誤用空指針的話將會讓程式crash崩潰,以下為空指針的範例程式碼,

1
2
int* ptr = nullptr;
*ptr = 5; // 將導致crash,因為ptr是空指針

如何避免:在使用指針之前,確保它們不是空指針。

未初始化的指針或指向無效記憶體的指針可能導致程式崩潰。務必在使用指針之前進行初始化,並謹慎檢查指針是否為NULL,修正空指針陷阱後的程式碼如下,

1
2
3
4
int* ptr = nullptr;
if (ptr != nullptr) {
*ptr = 5; // 不會crash
}

要確保在使用指針之前檢查它們是否為空指針。

以上就是 C/C++ 程式的常見陷阱與範例介紹,這些範例展示了 C/C++ 中的一些常見陷阱,以及如何避免它們。要寫出更健壯和安全的程式,需要謹慎處理這些問題,以確保程式碼的正確性和可靠性。
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ fopen 用法與範例
C/C++ fread 用法與範例
C/C++ fgets 用法與範例
C/C++ fputs 用法與範例
C/C++ fclose 用法與範例