C 語言允許函數回傳指標(地址),此類函數稱為指標函數。
#include <stdio.h>
#include <string.h>
char *strlong(char *str1, char *str2) {
if (strlen(str1) >= strlen(str2)) return str1;
else return str2;
}
int main() {
char str1[30], str2[30], *str;
gets(str1); gets(str2);
str = strlong(str1, str2);
printf("Longer string: %s\n", str);
return 0;
}
回傳的指標指向主調函數的區域陣列,生命週期涵蓋使用期間,安全有效。
int *func() {
int n = 100;
return &n; // 錯誤:回傳區域變數地址
}
函數結束後區域變數 n 被銷毀,記憶體所有權釋放,後續使用導致未定義行為。
int *func() { int n = 100; return &n; }
int main() {
int *p = func(), n;
n = *p; printf("value = %d\n", n); // 可能輸出 100
}
原因:函數返回後棧框記憶體暫未被覆蓋,若立即使用 僥倖讀到舊值。但這是極度不穩定的。
int main() {
int *p = func(), n;
printf("c.biancheng.net\n"); // 呼叫 puts 覆蓋棧空間
n = *p; printf("value = %d\n", n); // 輸出 -2 等亂碼
}
任何後續函數呼叫都會覆蓋棧上原 func 的棧框,導致資料損毀。
函數回傳指標絕不可指向函數內部的區域變數、區域陣列、形式參數。 應指向:主調函數提供的緩衝區、靜態/全域變數、動態分配記憶體(malloc)、字串常數。