首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言基礎

C 語言指標作為函數回傳值:指標函數與區域變數陷阱

     編輯:C 語言基礎

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)、字串常數。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved