C ++指针/ for-loop混淆

时间:2017-04-02 08:04:36

标签: c++ arrays pointers for-loop stdio

我正在尝试编写一个程序,使用指针从cin读取值,然后将值与它们在数组中的位置一起输出。我无法弄清楚为什么printNumbers1工作但printNumbers2没有。这是程序(底部附近的相关代码):

#include <iostream>

using namespace std;

int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);

int main()
{
    int *numbers = readNumbers(5);
    printNumbers1(numbers);
    printNumbers2(numbers);
    return 0;
}

int *readNumbers(int n)
{
    int a[n];
    int *numbers;
    numbers = &a[0];
    for (int i=0; i<n; i++)
    {
        cin >> *(numbers+i);
    }

    return numbers;
}

void printNumbers1(int *numbers)
{
    cout << 0 << ' ' << *(numbers) << endl
         << 1 << ' ' << *(numbers+1) << endl
         << 2 << ' ' << *(numbers+2) << endl
         << 3 << ' ' << *(numbers+3) << endl
         << 4 << ' ' << *(numbers+4) << endl;
}

void printNumbers2(int *numbers)
{
    for (int i=0; i<5; i++)
    {
        cout << i << ' ' << *(numbers+i) << endl;
    }
}

当我运行程序时,它按照printNumbers1的预期工作,但为printNumbers2输出看似随机数和0的组合。我觉得两个printNumbers函数应该应该具有相同的功能,但它们不应该。我错过了什么?

3 个答案:

答案 0 :(得分:2)

这是因为两件事的结合:

  • C ++不允许使用可变长度数组 - 这是一种流行的扩展,但声明int a[n]不是标准的。
  • 您无法从函数返回指向局部变量的指针 - numbers内的指针readNumbers指向本地变量a。你可以在函数内部使用这个指针,但是在函数之外它变得无效,因为a超出了范围。

使用超出范围的变量会导致未定义的行为This Q&A提供了对正在发生的事情的非常好的解释,以及为什么程序运行正常。

如果您想使用内置指针,请删除int a[n],然后按如下所示更改numbers的声明:

int *numbers = new int[n];

您还需要添加

delete[] numbers;

return 0行之前,以避免内存泄漏。

我假设您将此代码编写为学习练习的一部分。但总的来说,C ++中更好的方法是使用std::vector<int>来隐藏代码中的指针操作,并为您处理资源管理。

答案 1 :(得分:1)

readNumbers返回指向具有自动存储持续时间的变量的指针。

取消引用该指针的行为未定义。

使用std :: vector代替。依靠返回值优化来避免使用任何多余的值副本。

答案 2 :(得分:0)

这里你已经在函数内创建了数组a [n],所以它是一个局部变量,因此在函数范围结束后,这个数组可能被删除也可能不被删除。永远不要使用外部局部变量的地址功能。这段代码正在运行:

#include <iostream>

using namespace std;

int *readNumbers(int);
void printNumbers1(int*);
void printNumbers2(int*);

int main()
{
    int *numbers = readNumbers(5);
    printNumbers1(numbers);
    printNumbers2(numbers);
    return 0;
}

int *numbers;

int *readNumbers(int n)
{

    numbers = new int[n];
    for (int i=0; i<n; i++)
    {
         cin >> *(numbers+i);
    }

    return numbers;
}

void printNumbers1(int *numbers)
{ 
cout << 0 << ' ' << *(numbers) << endl
     << 1 << ' ' << *(numbers+1) << endl
     << 2 << ' ' << *(numbers+2) << endl
     << 3 << ' ' << *(numbers+3) << endl
     << 4 << ' ' << *(numbers+4) << endl;
}

void printNumbers2(int *numbers)
{
for (int i=0; i<5; i++)
{
    cout << i << ' ' << *(numbers+i) << endl;
}
}