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

C 語言字符串數組指針運算陷阱:常量區存儲不連續導致輸出異常

     編輯:程式設計疑難解答

代碼與現象

char *str[] = { "Welcome", "to", "Fortemedia", "Nanjing" };
char **p = str + 1;          // p 指向 "to"
str[0] = (*p++) + 2;         // str[0] 指向 "to" + 2 → "o"
cout << str[0] << endl;      // 輸出空行
str[0] += 1;                 // 指向 "o" 後的 '\0'
cout << str[0] << endl;      // 仍輸出空行
str[0] += 1;                 // 指向下一個字符串 "Fortemedia" 首地址
cout << str[0] << endl;      // 輸出 "Fortemedia"

核心誤區

假設字符串字面量在內存中首尾相連(如 "Welcome\0to\0Fortemedia\0Nanjing\0"),實際上編譯器將字符串字面量存放在常量區,不保證連續佈局。各字符串地址由編譯器獨立分配,可能相隔極遠。

內存佈局示意

地址 0x1000: "Welcome\0"
地址 0x2000: "to\0"
地址 0x3000: "Fortemedia\0"
地址 0x4000: "Nanjing\0"

str[0] = (*p++) + 2 使 str[0] 指向 "to" 的第 3 個字符(即 \0),輸出空字符串。指針遞增遍歷的是當前字符串內部,而非數組下一元素。

彩蛋驗證

char *str[] = {"Welcome", "to", "Welcome", "Nanjing"};
// 編譯器優化:相同字面量合併存儲,str[0] == str[2] 為 true

這證明字符串字面量由編譯器去重管理,地址分配完全不可預期。

結論

切勿假設字符串字面量連續存儲。需遍歷數組元素請使用下標 str[i] 或指針算術 *(str + i),而非嘗試跨字符串指針運算。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved