使用 C++ std::cin 时出现溢出错误,变量内有奇怪的值 (C++11)
Overflow error when using C++ std::cin, has strange value inside variable (C++11)
对于 C++ 程序,我实现了 2 个函数:
- 将数组大小作为输入并创建该大小的一维数组的 Make1DArray
- Make2DArray,获取行和列的大小并创建给定行和列大小的二维数组
主要函数如下所示:
int main()
{
cout << "enter 1d array length: ";
int x;
cin >> x;
Make1DArray(x);
cout << "enter 2d array row size: ";
int nrows, ncols;
cin >> nrows;
cout << "enter 2d array col size: ";
cin >> ncols;
Make2DArray(nrows, ncols);
return 0;
}
当我输入 x = 10000000000 (10^10) 时,程序输出不 运行 第二个函数并要求输入。消息输出如下所示:
enter 1d array length: 100000000000
enter 2d array row size: enter 2d array col size:
所以我检查了 x、nrow 和 ncol 的值,这些值是这样的:
- x = 2147483647
- n 行 = 0
- ncols = 32767
我用谷歌搜索了一下,发现当发生溢出错误时,cin 会为 x 分配最接近的值。
对于 nrows,我知道它可能会得到 0,因为发生了错误。
我不明白的是为什么第三个变量 ncols 被赋值为 32767。我确实发现 32767 是一个 short int 的最大值,但我不知道为什么变量 ncols 会得到这个值。
有人能给我解释一下吗?谢谢!
ETA:我不确定是否应该添加这两个函数,因为它们真的很简单,但为了以防万一,它们看起来像这样:
void Make1DArray(int arrSize) {
int *arr;
arr = (int *)malloc(arrSize * sizeof(int));
for (int i = 0; i < arrSize; i++)
{
arr[i] = i;
}
}
void Make2DArray(int nrows, int ncols) {
int **arr = (int **)malloc(nrows * sizeof(int *));
for (int i = 0; i < nrows; i++)
arr[i] = (int *)malloc(ncols * sizeof(int));
int count;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
{
arr[i][j] = ++count;
}
}
问题
问题是第一个溢出由于值溢出而设置了故障位。不执行后续读数,使 nrows
和 ncols
处于未定义状态。如果您初始化这些变量,您会注意到它们不会改变。
解决方案
不要使用 int
来保持尺寸,而是使用 size_t
。这应该适用于大多数编译器的示例图。
如果您希望您的代码是防弹的,请检查 cin
上的状态以查看输入是否有效并在必要时处理任何错误(包括 cin.clear()
以清除恢复读取前的失败状态)。
不相关:在您的函数代码中(顺便说一句,它会泄漏内存),也迭代 size_t
。并避免使用 malloc()
:在 C++ 中更喜欢使用 new
来动态创建对象。
对于 C++ 程序,我实现了 2 个函数:
- 将数组大小作为输入并创建该大小的一维数组的 Make1DArray
- Make2DArray,获取行和列的大小并创建给定行和列大小的二维数组
主要函数如下所示:
int main()
{
cout << "enter 1d array length: ";
int x;
cin >> x;
Make1DArray(x);
cout << "enter 2d array row size: ";
int nrows, ncols;
cin >> nrows;
cout << "enter 2d array col size: ";
cin >> ncols;
Make2DArray(nrows, ncols);
return 0;
}
当我输入 x = 10000000000 (10^10) 时,程序输出不 运行 第二个函数并要求输入。消息输出如下所示:
enter 1d array length: 100000000000
enter 2d array row size: enter 2d array col size:
所以我检查了 x、nrow 和 ncol 的值,这些值是这样的:
- x = 2147483647
- n 行 = 0
- ncols = 32767
我用谷歌搜索了一下,发现当发生溢出错误时,cin 会为 x 分配最接近的值。 对于 nrows,我知道它可能会得到 0,因为发生了错误。
我不明白的是为什么第三个变量 ncols 被赋值为 32767。我确实发现 32767 是一个 short int 的最大值,但我不知道为什么变量 ncols 会得到这个值。
有人能给我解释一下吗?谢谢!
ETA:我不确定是否应该添加这两个函数,因为它们真的很简单,但为了以防万一,它们看起来像这样:
void Make1DArray(int arrSize) {
int *arr;
arr = (int *)malloc(arrSize * sizeof(int));
for (int i = 0; i < arrSize; i++)
{
arr[i] = i;
}
}
void Make2DArray(int nrows, int ncols) {
int **arr = (int **)malloc(nrows * sizeof(int *));
for (int i = 0; i < nrows; i++)
arr[i] = (int *)malloc(ncols * sizeof(int));
int count;
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
{
arr[i][j] = ++count;
}
}
问题
问题是第一个溢出由于值溢出而设置了故障位。不执行后续读数,使 nrows
和 ncols
处于未定义状态。如果您初始化这些变量,您会注意到它们不会改变。
解决方案
不要使用
int
来保持尺寸,而是使用size_t
。这应该适用于大多数编译器的示例图。如果您希望您的代码是防弹的,请检查
cin
上的状态以查看输入是否有效并在必要时处理任何错误(包括cin.clear()
以清除恢复读取前的失败状态)。不相关:在您的函数代码中(顺便说一句,它会泄漏内存),也迭代
size_t
。并避免使用malloc()
:在 C++ 中更喜欢使用new
来动态创建对象。