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

C 語言字符數組未初始化導致 printf 輸出 hellohello:內存佈局與字符串結束符分析

     編輯:程式設計綜合問答

代碼:


char a[] = "hello"; // 實際為 {'h','e','l','l','o','\0'} 長度 6
char b[5] = {0};    // 5 個 0
// 內存佈局 (棧上連續分配,b 在低地址,a 在高地址):
// b[0] b[1] b[2] b[3] b[4] a[0] a[1] a[2] a[3] a[4] a[5]
//  0    0    0    0    0    h    e    l    l    o    \0

for (int i = 0; i < 5; ++i) b[i] = a[i]; // 複製 'h','e','l','l','o' 到 b
// 內存變為:
//  h    e    l    l    o    h    e    l    l    o    \0
// b[0]...b[4]    a[0]...a[5]

printf("%s", b); // 從 b[0] 尋找 '\0',發現於 a[5] 位置 → 輸出 "hellohello"

逐步分析

  1. 定義:a 包含結束符 \0 (長度 6);b 長度 5,**無結束符空間**。
  2. 棧內存連續:局部數組按聲明順序在棧上相鄰分配,b 低地址,a 高地址 (編譯器實現相關,但通常連續)。
  3. 複製循環:i=0..4 複製 a[0..4] ('h'..'o') 到 b[0..4]。**未複製 a[5] (\0)**。
  4. 內存結果:b 變為 "hello" (無 \0),緊接著是 a 的 "hello\0"。整個連續區無 \0 直到 a 末尾。
  5. printf 行為:%s 從 b 起始地址尋找首個 \0,跨過 b 5 字節、a 前 5 字節,在 a[5] 找到 → 輸出 10 字符 "hellohello"。

修正方法


// 1. 留出結束符空間
char b[6] = {0}; 
// 或
char b[sizeof(a)]; // 自動匹配大小

// 2. 複製包含結束符
strcpy(b, a); // 安全、標準
// 或
memcpy(b, a, sizeof(a)); // 精確複製 6 字節
// 或循環
for (int i = 0; i < sizeof(a); ++i) b[i] = a[i];

核心教訓

  • **字符串操作必須包含結束符 \0**。
  • 目標緩衝區大小 ≥ 源字符串長度 + 1。
  • 優先使用 strcpy/strncpy/memcpy 等標準庫函數,避免手寫循環漏掉 \0。
  • 棧上數組相鄰分配是實現細節,**不可依賴** 此行為,但解釋了該現象。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved