首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言字串指標陣列賦值錯誤:未初始化指標導致未定義行為,正確寫法與記憶體配置詳解

     編輯:程式設計綜合問答

錯誤程式碼分析


char *a[2];          // 宣告兩個 char* 指標,但**未初始化** (野指標)
char *d;
scanf("%s%s", a[0], a[1]); // 將輸入寫入野指標指向的隨機記憶體 → 崩潰/資料損壞
if (strcmp(a[0], a[1]) > 0) { d=a[0]; a[0]=a[1]; a[1]=d; }
printf("%s\n", a);   // %s 期望 char*,傳入 char** → 格式錯誤

核心問題:指標 ≠ 記憶體空間

  • `char *a[2]` 只分配了 **2 個指標變數** (各 8 bytes/64-bit),**未分配字串儲存空間**
  • 指標值為隨機垃圾值 (野指標),`scanf` 寫入隨機位址 → **未定義行為**

正確寫法三種 (依需求選擇)

方法 1:靜態陣列緩衝區 (最簡單、教學常用)


#include 
#include 

int main() {
    char str1[80], str2[80];        // 1. 分配實際字串儲存空間 (各 80 bytes)
    char *a[2];                     // 2. 指標陣列
    char *d;

    a[0] = str1;                    // 3. 指標指向有效緩衝區
    a[1] = str2;

    printf("請輸入兩個字串:");
    scanf("%79s %79s", a[0], a[1]); // 限制寬度防溢位

    if (strcmp(a[0], a[1]) > 0) {
        d = a[0]; a[0] = a[1]; a[1] = d;
    }
    printf("較小: %s\n", a[0]);     // 正確:傳入 char*
    printf("較大: %s\n", a[1]);
    return 0;
}

方法 2:動態記憶體分配 (malloc/free,長度不固定)


#include 
#include 
#include 

int main() {
    char *a[2];
    char input[100];
    char *d;

    for (int i = 0; i < 2; i++) {
        printf("字串 %d: ", i+1);
        scanf("%99s", input);
        a[i] = malloc(strlen(input) + 1); // 精確分配
        if (!a[i]) { perror("malloc"); return 1; }
        strcpy(a[i], input);
    }

    if (strcmp(a[0], a[1]) > 0) { d=a[0]; a[0]=a[1]; a[1]=d; }
    printf("排序後: %s, %s\n", a[0], a[1]);

    free(a[0]); free(a[1]); // 釋放記憶體
    return 0;
}

方法 3:C99 變長陣列 (VLA,僅限區塊作用域)


int len1, len2;
scanf("%d %d", &len1, &len2); // 先讀長度 (教學示範)
char str1[len1+1], str2[len2+1]; // VLA
scanf("%s %s", str1, str2);
// ...後續同方法 1

關鍵觀念對照表

宣告記憶體配置可直接存字串?適用場景
`char str[80];`堆疊 80 bytes✅固定最大長度、生命週期跟隨區塊
`char *p;`堆疊 1 個指標 (8 bytes)❌ 需指向有效空間指向現有字串、動態分配
`char *a[2];`堆疊 2 個指標❌字串指標陣列、參數傳遞
`char **p;`指向指標的指標❌動態二維字串、主函數 argv

原程式碼其他錯誤修正

  • `printf("%s\n", a);` → `printf("%s\n", a[0]);` (或迴圈印 a[0], a[1])
  • `scanf("%s%s", ...)` → `scanf("%79s %79s", ...)` **限制寬度**防緩衝區溢位
  • `main()` → `int main(void)` 標準簽名

總結

**字串指標陣列必須指向有效記憶體空間** (靜態陣列、動態分配、VLA)。`char *a[2]` 僅建立指標,**不配置字串儲存空間**。教學首選**靜態陣列緩衝區 + 指標指向**,簡單安全;實務長度不定用 **`malloc`/`free`**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved