运行时先声明动态数组再获长度引发的异常行为咨询
未初始化变量定义变长数组导致的内存覆盖问题分析
问题代码
#include <cstdio> #include <iostream> using namespace std; int main() { int length; int ar[length]; cout << "Enter the length of array: "; cin >> length; cout << "--- length before: " << length << endl; cout << "Provide " << length << " integer values separated by space and then press Enter." << endl; for (int i = 0; i<length; i++) { cin >> ar[i]; cout << "i: " << i << " - ar[i]: " << ar[i] << endl; } cout << "--- length after: " << length << endl; return 0; }
测试输出
Enter the length of array: 5 --- length before: 5 Provide 5 integer values separated by space and then press Enter. 4 3 7 2 1 i: 0 - ar[i]: 4 i: 3 - ar[i]: -1 --- length after: 4
异常行为的根源
未初始化变量的未定义行为
你声明了int length;但未初始化,局部变量默认是栈上的随机垃圾值。此时用int ar[length];定义数组,数组大小是这个垃圾值,这本身就属于C++标准中的未定义行为——任何奇怪的结果都可能出现。非标准变长数组(VLA)的风险
C++标准并不支持变长数组,这是GCC等编译器提供的非标准扩展。这类数组直接分配在栈上,和其他局部变量的内存空间紧密相邻,极易引发内存越界覆盖。内存覆盖篡改变量值
栈空间通常是向下增长的,先声明的变量会占据更高的内存地址。length先声明,ar数组紧随其后,当数组大小为垃圾值时,ar[0]的内存位置刚好和length的内存地址重叠。所以你输入第一个数字4时,实际上是把length的值从5改成了4,这就解释了最终length after变成4的原因。循环变量被越界访问篡改
循环里的i也是栈上的局部变量,后续输入的数值触发数组越界,直接覆盖了i的内存位置,导致i的值跳变,出现输出中i从0跳到3的异常。
正确实现方式
要避免这类问题,应该先获取数组长度,再用C++标准的动态数组管理方式:
#include <iostream> #include <vector> using namespace std; int main() { int length; cout << "Enter the length of array: "; cin >> length; vector<int> ar(length); // 用vector安全管理动态数组 cout << "Provide " << length << " integer values separated by space and then press Enter." << endl; for (int i = 0; i < length; i++) { cin >> ar[i]; cout << "i: " << i << " - ar[i]: " << ar[i] << endl; } cout << "--- length after: " << length << endl; return 0; }
也可以手动用new分配内存(注意用完后释放):
int* ar = new int[length]; // 使用数组逻辑... delete[] ar; // 必须释放内存,避免泄漏
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

