C++ 函式返回區域變數位址是經典錯誤,導致未定義行為與難以重現的崩潰。本文剖析錯誤成因、實測驗證,並提供多種安全替代模式。
char* Func_Error() {
char str[30] = "Bruce"; // 區域陣列,儲存於堆疊
cout << "str: " << str << endl;
return str; // 錯誤:返回區域變數位址
}
#include <iostream>
#include <cstring>
using namespace std;
const char* testValue = "BruceZhang";
char gstr[30] = {0}; // 全域變數,靜態儲存區
char* Func_Bad() {
char str[30] = "Bruce";
cout << "str: " << str << endl;
return str; // 危險!
}
char* Func_Good() {
strcpy(gstr, testValue); // 複製至全域緩衝區
cout << "gstr: " << gstr << endl;
return gstr; // 安全:全域變數生命週期贏過程式
}
int main() {
char* bad = Func_Bad();
char* good = Func_Good();
cout << "bad: " << bad << endl; // 輸出亂碼
cout << "good: " << good << endl; // 正常輸出
return 0;
}

| 方案 | 適用場景 | 範例 |
|---|---|---|
| 返回 std::string | 現代 C++ 首選,自動管理記憶體 | std::string func() { return "Bruce"; } |
| 呼叫端提供緩衝區 | C 風格 API、效能敏感場合 | void func(char* buf, size_t len); |
| 返回動態配置記憶體 | 需呼叫端負責釋放(易洩漏) | char* func() { return strdup("Bruce"); } |
| 使用 static 區域變數 | 單執行緒、唯一實例需求 | char* func() { static char buf[30]; return buf; } |
| 返回結構體/類別封裝資料 | 複雜資料結構 | struct Result { std::string data; }; |
std::string、std::vector 等 RAII 容器。-Wreturn-local-addr (GCC/Clang) 或 /W4 (MSVC)。