C++ 指针在 for 循环中被覆盖

Posted

技术标签:

【中文标题】C++ 指针在 for 循环中被覆盖【英文标题】:C++ pointer gets overwritten in for loops 【发布时间】:2020-02-10 03:02:43 【问题描述】:

有人能解释一下为什么在循环中声明变量时指针会被覆盖吗?

例如,给定以下 sn-p,并且用户输入 1 和 2。我希望 pNums 数组包含 2 个指针,指向分别保存值 1 和 2 的 2 个整数。

但是,控制台会打印出22

#include <iostream>
using namespace std;

//Input "1 2"
int main() 
    int* pNums[2];
    for(int i = 0; i < 2; i++)
        int num;
        cin >> num;
        pNums[i] = (&num);
    
    cout << (*pNums[0]) << endl;
    cout << (*pNums[1]) << endl; 

为什么会这样?我该如何解决?例如,如果我们不知道用户将输入多少个数字,而不是for 循环,我们有一个while 循环怎么办?在满足某些条件之前,我们要不断创建新指针并将它们存储到pNums 向量中?

【问题讨论】:

int 变量实际上只声明了一次 for all for 循环迭代,因此共享相同的内存。您想查看动态变量并使用 new/delete。或者更改为使用另一种方法,例如 std::vector 列表,您可以在其中将数字添加到列表中。 为什么要不断创建新的指针?你不想要新的吗?如果没有新的东西可以指向,那么创建新指针的目的是什么? 【参考方案1】:

只有一个num,而您正在覆盖那个。(然后导致未定义的行为,但不要介意。)

有两种简单的方法可以避免这个错误。

1) 存储对象,而不是指针:

int nums[2];
for(int i = 0; i < 2; i++)
    cin >> nums[i];

2) 使用动态分配:

int* pNums[2];
for(int i = 0; i < 2; i++)
    int *p=new int;
    cin >> *p;
    pNums[i] = p;

【讨论】:

但记得删除你声明的数据以避免内存泄漏。或者使用智能指针。 @AndrewTruckle 如果我们使用动态分配,何时/如何删除数据?什么是智能指针?如果这里解释的时间太长,能否请您指点我的教程或文档? @Synia 见geeksforgeeks.org/… 和docs.microsoft.com/en-us/cpp/cpp/…。一个很好的教程将解释这些方法。【参考方案2】:

您存储在pNums 中的指针指向for 块中变量num 的两个实例。在每个for 循环迭代中都有一个变量实例,这些变量只存在到它们各自的for 循环体迭代结束。

因此,当for 循环退出时,您的指针将无效,因此尝试使用例如取消引用它们*pNums[0] 导致 undefined behavior

不存储指针,存储值:

#include <iostream>
using namespace std;

//Input "1 2"
int main() 
    int pNums[2];
    for(int i = 0; i < 2; i++)
        int num;
        cin >> num;
        pNums[i] = num;
    
    cout << pNums[0] << endl;
    cout << pNums[1] << endl; 

如果您需要数组中可变数量的条目,请使用std::vector

【讨论】:

【参考方案3】:
for(int i = 0; i < 2; i++)
    int num; //< this is num. It lives here.
    cin >> num; 
    pNums[i] = (&num);  //< you have taken the address of num (twice!)

// here is when 'num' is destroyed (no longer in scope)

// so this is now pointing at something that doesn't exist. 
cout << (*pNums[0]) << endl;

【讨论】:

以上是关于C++ 指针在 for 循环中被覆盖的主要内容,如果未能解决你的问题,请参考以下文章

c ++如何创建一个即使在对象被覆盖时也会持续的指针?

C ++从向量中删除指针会导致堆错误

使用条件 while/for 循环的指针在编译时会出错

for循环最后一次迭代的指针变化

喵呜:C++基础系列:auto关键字(C++11)基于范围的for循环(C++11)指针空值nullptr(C++11)

喵呜:C++基础系列:auto关键字(C++11)基于范围的for循环(C++11)指针空值nullptr(C++11)