我正在尝试编写一个程序,使用指针从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函数应该应该具有相同的功能,但它们不应该。我错过了什么?
答案 0 :(得分:2)
这是因为两件事的结合:
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;
}
}