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

C語言字符串指針排序導致內存非法訪問的解決

     編輯:程式設計綜合問答

問題現象

使用指針數組對字符串進行選擇排序時,程序在 strcpy(p[k], p[i]) 處觸發「內存訪問非法」錯誤。

錯誤代碼

char ss[10][5] = {"worin","trafi","panda","dalai","lama2","strin","tende","racof","lenth","recte"};

void sort(char p[][5]) {
    char temp[20];
    for (int i = 0; i < 9; i++) {
        int k = i;
        for (int j = i + 1; j < 10; j++)
            if (strcmp(p[k], p[j]) > 0) k = j;
        if (k != i) {
            strcpy(temp, p[k]);      // 複制第 k 個字符串
            strcpy(p[k], p[i]);      // 此處崩潰
            strcpy(p[i], temp);
        }
    }
}

根本原因

數組定義 char ss[10][5] 中,每行僅分配 5 個字節,但字符串如 "worin" 長度為 5,**缺少結束符 '\0'**,實際需要 6 字節。導致:

  • 字符串在內存中連續存放,無結束符分隔。
  • strcpy 讀寫越界,破壞相鄰數據或訪問非法地址。

解決方案

1. 擴大數組列尺寸

char ss[10][6] = { ... }; // 至少 max_len + 1

2. 或使用指針數組指向字符串常量

char *ss[10] = {"worin", "trafi", ...}; // 僅存指針,字符串放在只讀區
// 排序時交換指針而非複製內容,效率更高
void sort(char *p[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int k = i;
        for (int j = i + 1; j < n; j++)
            if (strcmp(p[k], p[j]) > 0) k = j;
        if (k != i) {
            char *tmp = p[k];
            p[k] = p[i];
            p[i] = tmp;
        }
    }
}

3. 若必須修改字符串內容,動態分配

char **ss = malloc(10 * sizeof(char*));
for (int i = 0; i < 10; i++) {
    ss[i] = strdup(initial_strings[i]); // 含結束符
}
// 排序後記得 free 每個 ss[i] 及 ss 本身

最佳實踐建議

  • **始終為字符串預留結束符空間**:定義數組時列數 = 最大長度 + 1。
  • **優先使用指針數組 + 交換指針**排序,避免 strcpy 開銷與越界風險。
  • 使用 strncpy 或 snprintf 替代 strcpy,指定最大長度防止溢出。
  • 啟用編譯器警告(-Wall -Wextra 或 /W4),可捕獲數組越界等隱患。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved