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

C語言指針賦值字符串常量:本質是首地址賦值,而非複製內容

     編輯:程式設計綜合問答

核心結論

`char *ptr = "hello";` **不會複製字符串內容**,而是:

  1. 編譯器在 **只讀數據段** (`.rodata`) 存儲字符串常量 `"hello\0"`。
  2. 將該字符串的 **首字符地址** (如 `0x400000`) 賦值給指針變量 `ptr`。
  3. `ptr` 現在指向只讀內存區,**不可通過 `ptr` 修改內容** (運行時崩潰: Segmentation Fault / Access Violation)。

內存模型圖解


// 代碼
char *p1 = "hello";
char *p2 = "hello";
char arr[] = "hello";

// 內存佈局 (概念圖)
只讀數據段 (.rodata)          棧/數據段
+-------------------+          +-------------------+
| 'h','e','l','l','o','\0' | ← p1 (0x400000)     | p1 指針變量 (8字節) |
|                   | ← p2 (0x400000)     | p2 指針變量 (8字節) |
+-------------------+          | arr[6] (可修改)    |
                               +-------------------+
// p1 == p2 為 true (編譯器優化合併相同字面量)
// arr 獨立拷貝一份,可修改 arr[0] = 'H'

常見錯誤與修正

錯誤代碼問題修正
`char *p = "hello"; p[0] = 'H';`嘗試修改只讀內存 → 崩潰`char p[] = "hello"; p[0] = 'H';` (數組在棧上,可寫)
`char *p; scanf("%s", p);``p` 未指向有效內存 → 野指針崩潰`char buf[100]; scanf("%s", buf);` 或 `malloc` 分配
`char *p = malloc(10); p = "hello";`內存洩漏 (malloc 內存丟失),`p` 指向只讀區`strcpy(p, "hello");` 複製內容到堆內存

字符串常量 vs 字符數組

  • **字符串常量** (`"..."`):存儲在只讀區,類型 `const char[]`,不可修改,編譯期確定地址。
  • **字符數組** (`char s[] = "..."`):存儲在棧/數據段,**自動複製**常量內容,可修改,每次進入作用域分配。

最佳實踐

  • 只讀字符串指針聲明為 `const char *p = "..."`,編譯器阻止誤寫。
  • 需要修改/輸入字符串 → 定義數組 `char buf[N]` 或動態分配 `malloc`/`new`。
  • 函數參數接收只讀字符串 → `void func(const char *str)`。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved