在 C 語言中,定義字符串數組時常見兩種寫法:
char *ptr[10]; // 指針數組
char ptr[10][20]; // 二維數組
初學者常困惑:為什麼第一種配合 gets(ptr[0]) 會運行出錯,而第二種卻正常?
這定義了一個包含 10 個 char* 指針的數組。每個指針初始化為野指針(未指向有效內存)。調用 gets(ptr[0]) 時,試圖向未分配的內存寫入數據,導致未定義行為(通常是段錯誤)。
這在棧上連續分配了 10 × 20 = 200 個字節的內存空間,每行固定 20 個字符。ptr[0] 直接指向第一行的首地址,gets(ptr[0]) 寫入的是已分配的合法內存,因此正常工作。
這類似於一維情況下的 int *p; 與 int a[10];:前者只是指針,需先 malloc 或指向現有變量;後者自帶存儲空間。
若必須用 char *ptr[10],需為每個指針分配內存:
for (int i = 0; i < 10; ++i) {
ptr[i] = malloc(20 * sizeof(char)); // 或指向靜態緩衝區
}
gets(ptr[0]); // 現在安全了
// 使用後記得 free
fgets() 並指定長度。