代碼嘗試修改字符串字面量內容:
char *p = "I love you China, do you love me?";
*p = 'X'; // 運行時崩潰:Access Violation / Segmentation Fault
編譯無錯誤,但運行時觸發內存保護異常。
| 定義方式 | 存儲區域 | 可修改性 | 生命周期 |
|---|---|---|---|
char *p = "abc"; | .rodata (只讀數據段) | 不可修改 | 程序全周期 |
char p[] = "abc"; | 棧 (Stack) | 可修改 | 作用域結束 |
char *str = "hello";
str[0] = 'H'; // Crash!
char str[] = "hello"; // 相當於 char str[6] = {'h','e','l','l','o','\0'};
str[0] = 'H'; // OK,修改棧上副本
char *str = malloc(6);
strcpy(str, "hello");
str[0] = 'H'; // OK,堆內存可讀寫
free(str);
const 修飾指針(編譯期攔截)const char *str = "hello";
// str[0] = 'H'; // 編譯錯誤:assignment of read-only location
const 關鍵字,字面量類型為 char* 而非 const char*"error" 只存一份現代編譯器(GCC/Clang/MSVC)均提供編譯警告:-Wwrite-strings 會將字面量類型視為 const char*,賦值給非 const 指針時發出警告。
watch *(char*)0xADDRESS 監視內存寫入--track-origins=yes 追蹤非法寫入源頭-fsanitize=address 精準報錯const:const char *msg = "text"; 讓編譯器幫你擋錯char buf[] = "text"; 自動分配可寫副本malloc/strdup 並記得 free-Wall -Wextra -Wwrite-strings (GCC/Clang) 或 /W4 (MSVC)C++ 標準規定字符串字面量類型為 const char[N],因此:
char *p = "hello"; // C++11 起廢棄,C++20 移除(編譯錯誤)
const char *p = "hello"; // 標準寫法
auto p = "hello"; // 推導為 const char*
這是 C/C++ 互操作時的常見坑點之一。