c++ - 尝试读取数组c ++时,for循环崩溃程序
问题描述
练习:给定向量 A[1 to N] 和一个值 s。构建将每组 s 元素反向写入的程序。如果 s 除以 N 有余数,则余数应保持不变。如果 s 大于 N(向量的元素的 nr 个),则不会有任何修改。
假设 s = 4 和 A = (1, 2, 3, 4, 5, 6, 7, 8),那么执行后的值将是 A = (4, 3, 2, 1, 8, 7, 6, 5 )
我的老师需要这种向量: int n, A[n] 其中 n 是用户给定的值。我认为这是导致我的程序在读取最终值时崩溃的原因。如果不是,问题出在哪里?
#include <iomanip>
using namespace std;
int ordering(int s, int n, int A[]);
int main()
{
int n, A[n];
int s;
cout << "Vlera e s: ";
cin >> s;
if (s <= 0)
{
return 1;
}
cout << "\nN: ";
cin >> n;
if (n <= 0)
{
return 1;
}
cout << "\nVector:";
for (int i = 0; i < n; i++)
{
A[i] = i + 1;
cout << " " << A[i] << " ";
}
if (s > n)
{
cout << "\nNo change\n";
return 0;
}
else
{
ordering(s, n, A);
}
cout << "\nNew vector:";
for (int i = 0; i < n; i++)
{
cout << " " << A[i] << " ";
}
return 0;
}
int ordering(int s, int n, int A[])
{
int counter = 0;
for (int i = 0, divider = n / s; i < divider; i++)
{
int decrease = 0;
for (int j = counter, a = counter + s; j < a; j++)
{
A[j] = a - decrease;
decrease++;
}
counter += s;
}
return 0;
}
解决方案
这个程序使用一个编译器扩展来允许可变大小的数组形式myArray[variableSize]
。虽然不是标准的,但它确实适用于某些编译器。
您在此处使用此功能:
int n, A[n];
但是,n
此时未初始化。即使在支持这种可变大小数组的编译器上,这也是未定义的行为。未定义行为的一种可能(但不是唯一)结果是您的程序崩溃。
未定义的行为在理论上可以做任何事情,但在现实中可以做的事情的现实集合更小。此处未定义行为的一些可能含义:
n
里面有一些巨大的数字,无论最后一次使用了那一点内存。结果,A
是巨大的。n
是 0。你不能有一个 0 大小的数组。如果编译器没有注意到这一点,您最终可能会浪费内存。- 由于
n
未初始化,因此编译器的优化器(它们通常会进行一些优化,即使在 -O0 时也是如此)假定不会发生未定义的行为,这在此处被违反,导致奇怪的行为。 n
是一个合理的值,只是运气好,但是因为它后来被更新,它不再与数组的大小匹配,你最终会从数组的末尾读取/写入内存,从而浪费内存。
还有其他可能性,但这给出了由于这种未定义行为的特定实例而可能发生的事情的一种想法。如果您有兴趣了解更多信息,使用调试器在汇编中逐步执行代码(您只需要了解一点即可理解输出,它看起来比实际需要的更可怕)将向您展示实际发生的情况。
推荐阅读
- cpu-architecture - 为什么 LEGv8 中 d 格式的 9 位地址意味着寄存器可以加载基址寄存器 Rn 中地址的 2^8 字节的双字?
- html - 如何将页脚推到页面底部
- r - 从lmList绘制β系数?
- python - 如何获取 Django 模型的多对多字段总数?
- android - 双卡铃声 Uri
- python - 将 3d 张量输入 CNN 和 keras 网络时出现尺寸错误
- android - React-Native 构建 apk 组件不在设备上运行
- c# - 是否可以为非 UI 工作线程创建 Dispatcher (System.Windows.Threading)?
- rest - 在 Flask REST API 代码中生成 SQLite 数据库
- python - 卡在这里制作 Instagram 机器人