使用指針數組對字符串進行選擇排序時,程序在 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 讀寫越界,破壞相鄰數據或訪問非法地址。char ss[10][6] = { ... }; // 至少 max_len + 1
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;
}
}
}
char **ss = malloc(10 * sizeof(char*));
for (int i = 0; i < 10; i++) {
ss[i] = strdup(initial_strings[i]); // 含結束符
}
// 排序後記得 free 每個 ss[i] 及 ss 本身
strcpy 開銷與越界風險。strncpy 或 snprintf 替代 strcpy,指定最大長度防止溢出。-Wall -Wextra 或 /W4),可捕獲數組越界等隱患。