函數返回值本質是將表達式結果放入返回值暫存器(或結構體時用隱藏參數傳遞地址)。關鍵在於返回指標/引用時,所指記憶體必須在調用者使用期間保持有效。
int* fun() {
static int arr[] = {1,2,3,4,5}; // 靜態儲存區,程式結束前有效
return arr;
}
char* fun() {
return "hello"; // 字串常值存於唯讀資料段,永久有效
}
char* fun() {
char str[] = "hello"; // 堆疊陣列,函數返回即銷毀
return str; // 返回懸空指標,行為未定義
}
差異:char *str = "hello" 指向常值區;char str[] = "hello" 在堆疊複製常值內容。
struct S { int a,b,c; };
S fun() { S s = {1,2,3}; return s; } // 返回值優化 (RVO) 或拷貝至調用者空間
int main() { S s2 = fun(); } // s2 獲得副本,安全
static 區域、全域、命名空間作用域。malloc/new,調用者負責 free/delete(易洩漏,建議封裝智慧指針)。"text"、const 全域陣列。void fill(char* buf, size_t n),所有權清晰。void (*fp)() = &func;。高地址 ├── 栈 (Stack) ← 函數區域變量、參數、返回地址,自動管理,向下增長 ├── 堆 (Heap) ← malloc/new,手動管理,向上增長 ├── BSS 段 ← 未初始化靜態/全域變量 ├── Data 段 ← 已初始化靜態/全域變量 ├── 只读数据段 (rodata) ← 字串常值、const 全域 └── 代碼段 (Text) ← 函數機器碼 低地址
「返回指標,問壽命:靜態全域常值安,動態分配調用管,棧上區域最危險。」
理解記憶體模型與生命週期,是寫出健壯 C/C++ 代碼的核心功力。