C 語言不能直接返回局部數組(棧上分配,函數結束即銷毀)。正確做法有三種:
static,位於全局/靜態區)。malloc/new,位於堆區,調用者負責 free)。[cpp]
char* str() {
char str2[10] = "askdfjk"; // 棧上
return str2; // 返回棧地址,調用後內容不可預期
}
反汇编顯示:函數返回 lea -10(%ebp), %eax,指向已銷毀的棧幀。
[cpp]
char* str() {
static char str2[10] = "askdfjk"; // 靜態區,生命周期贯穿整個程序
return str2;
}
[cpp]
char* str() {
char *str2 = malloc(10 * sizeof(*str2));
strcpy(str2, "ababab"); // 必須逐字符拷貝或用 strcpy
return str2; // 堆內存不會自動釋放
}
int main() {
char *p = str();
printf("%s", p);
free(p); // 必須手動釋放
return 0;
}
注意:str2 = "ababab"; 會導致內存洩漏(丟失 malloc 的地址),必須用 strcpy 或逐字符賦值。
| 區域 | 存放內容 | 管理方式 |
|---|---|---|
| 代碼區 | 函數二進制碼 | 系統 |
| 常量區 | 字符串字面量 | 系統 |
| 全局/靜態區 | 全局變量、static 變量 | 系統 |
| 堆區 | malloc/new 分配內存 | 程序員 |
| 棧區 | 局部變量、參數、返回地址 | 編譯器自動 |
編譯器生成的代碼段固定,棧幀佈局固定;返回的棧地址指向舊棧幀,其內容隨後續函數調用被覆寫,前部恰好未被覆蓋,故顯示「固定前綴 + 隨機後綴」。
void func(char *buf, size_t len)。free」。