char *ptr = " asd as,vs aw"; // 指向只讀數據段
delspace(ptr); // 嘗試修改內容 → 段錯誤/SIGSEGV
void delspace(char *ps) {
char *pt = ps;
while (*ps) {
if (*ps != ' ') *pt++ = *ps; // 寫入只讀內存
ps++;
}
*pt = '\0';
}
char *ptr = "literal" 使 ptr 指向**只讀數據段**(.rodata),任何修改嘗試觸發硬件保護異常。編譯器不報錯是歷史兼容性妥協(C89 允許),但 C++11 已棄用,現代編譯器會警告。
char ptr[] = " asd as,vs aw"; // 編譯器在棧上分配數組並拷貝字面量
delspace(ptr); // 安全修改
char *ptr = strdup(" asd as,vs aw"); // malloc + strcpy
delspace(ptr);
free(ptr); // 記得釋放
const char *ptr = " asd as,vs aw"; // 編譯期禁止修改
// delspace(ptr); // 編譯錯誤:丟棄 const 資格
// 需修改函數簽名:
void delspace(const char *src, char *dest); // 輸出到目標緩衝區
char *p1 = "hello"; // p1 ──────► [.rodata] "hello\0" (只讀)
char p2[] = "hello"; // p2 ──────► [.stack] "hello\0" (可讀寫)
char *p3 = malloc(6); strcpy(p3, "hello"); // p3 ──► [.heap] "hello\0" (可讀寫)
const char *s = "..."char s[] = "..."void f(const char *p)-Wwrite-strings (GCC/Clang) / /W4 (MSVC)**一字之差**:*ptr vs ptr[],決定運行時崩潰與正常運行的分水嶺。