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

C語言指針數組遍歷陷阱:指針修改導致原數組地址被改變的深度分析

     編輯:程式設計綜合問答

問題代碼


char *p[] = {"to","yes","is ok","how do you do ?","holle"};
int main() {
    int a[5] = {0};
    char **t = p;
    
    // 打印原始地址
    for(int i=0;i<5;i++) printf("%x\t", p[i]);
    
    // 計算字符串長度 - 錯誤方式
    for(int i=0;i<5;i++) {
        while(*t[i] != '\0') {
            t[i]++;  // 錯誤:修改了原數組指針!
            a[i]++;
        }
    }
    
    // 打印長度
    for(int i=0;i<5;i++) printf("%d\n", a[i]);
    
    // 打印地址 - 已被改變!
    for(int i=0;i<5;i++) printf("%x\t", p[i]);
}

錯誤分析

t[i]++ 直接修改了 p 數組中的指針值,導致原字符串起始地址丟失。

執行前: p[0] → "to\0" (地址 0x403000)
執行後: p[0] → "o\0"   (地址 0x403001)  ← 指針後移!

正確實現


char *p[] = {"to","yes","is ok","how do you do ?","holle"};
int main() {
    int a[5] = {0};
    
    for(int i=0;i<5;i++) printf("%x\t", p[i]);
    printf("\n");
    
    for(int i=0;i<5;i++) {
        char *t = p[i];  // 關鍵:使用臨時指針副本
        while(*t != '\0') {
            t++;         // 修改副本,不影響原數組
            a[i]++;
        }
    }
    
    for(int i=0;i<5;i++) printf("%d\n", a[i]);
    for(int i=0;i<5;i++) printf("%x\t", p[i]); // 地址保持不變
    printf("\n");
}

核心概念對比

操作t[i]++t++ (t為副本)
影響對象原數組 p 中的指針局部變量 t (棧上副本)
原字符串起始地址丟失完全保持不變
適用場景需要永久修改指針臨時遍歷/計算

內存模型圖解

棧內存:                    堆/數據區:
t (局部變量) ──────┐       p[0] ──→ "to\0" (只讀)
                   │       p[1] ──→ "yes\0"
t = p[0] (複製地址)┘
t++ 只移動局部副本

最佳實踐原則

  1. 遍歷字符串時始終使用臨時指針副本
  2. 字符串字面量存儲在只讀數據區,不可修改內容
  3. 指針數組元素是指針變量,可修改指向,但謹慎操作
  4. 調試時打印指針地址驗證是否被意外修改
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved