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

C++ 動態指針地址變化導致二次輸出異常:指針算術修改原地址

     編輯:程式設計綜合問答

問題代碼

string str1;
cin >> str1;
char *Num1 = new char[str1.length()];
int *num1 = new int[str1.length()];
str1.copy(Num1, str1.length(), 0);

for (int i = 0; i < str1.length(); i++) {
    *num1 = *Num1 - '0';  // 轉數字
    cout << *num1 << endl;
    cout << num1 << endl; // 輸出地址
    num1++;   // ← 修改指針本身
    Num1++;
}
// 第二次循環輸出 num1 時地址已偏移,值為垃圾/崩潰

根因分析

指針算術 (`num1++`) 永久改變了指針指向的地址**。第一次循環結束後,`num1` 指向分配內存末尾之後,第二次循環讀取非法內存。

修正方案一:保存基地址

int *num1 = new int[str1.length()];
int *base = num1;  // 保存起始地址

for (int i = 0; i < str1.length(); i++) {
    *num1 = *Num1 - '0';
    cout << *num1 << ' ' << num1 << endl;
    num1++; Num1++;
}

num1 = base; // 重置指針
for (int i = 0; i < str1.length(); i++) {
    cout << *num1 << ' ' << num1 << endl;
    num1++;
}

修正方案二:使用下標訪問 (推薦,避免指針算術)

for (int i = 0; i < str1.length(); i++) {
    num1[i] = Num1[i] - '0';
    cout << num1[i] << ' ' << &num1[i] << endl;
}
// 後續直接用 num1[i] 訪問,指針 num1 始終指向數組首地址

修正方案三:標準庫容器 (現代 C++ 最佳實踐)

#include 
#include 

string str1; cin >> str1;
vector nums;
nums.reserve(str1.length());
for (char c : str1) {
    if (isdigit(c)) nums.push_back(c - '0');
}

// 輸出
for (size_t i = 0; i < nums.size(); ++i)
    cout << nums[i] << ' ' << &nums[i] << endl;
// vector 內存連續,&nums[i] 等價於 nums.data() + i

內存泄漏提醒

原代碼 `new char[]` / `new int[]` **未調用 `delete[]`**。修正版必須配對釋放:

delete[] Num1;
delete[] num1; // 或 base

方案三 `vector` 自動管理內存,無泄漏風險。

關鍵概念總結

操作效果是否修改指針值
ptr++指向下一個元素是 (永久)
ptr[i]訪問第 i 個元素否
*(ptr + i)訪問第 i 個元素否 (臨時計算)

總結

**指針算術會改變指針本身**。需保存基地址或改用下標/標準容器訪問。現代 C++ 優先用 `vector` 替代手動 `new[]/delete[]`。

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