反转for循环后printArrInt函数执行异常求助
问题分析与解决
问题背景
尝试将数组中的整数绘制成垂直等长的条形图,初始代码绘制的图形倒置,反转for循环后,首次调用函数正常,但第二次调用时要么完全失效,要么仅打印部分数组内容(每次运行结果还会变化)。
修改前代码
void printArrInt(int arr[], int len) { int max = findMaxValue(arr, len); std::string bars[len]; for (int i = 0; i < len; i++) { for (int j = 0; j < arr[i]; j++) { bars[i].append("@"); } for (int j = 0; j < (max - arr[i]); j++) { bars[i].append(" "); } } for (int i = 0; i < max; i++) { for (int j = 0; j < len; j++) { std::cout << bars[j][i]; } std::cout << std::endl; } std::cout << std::endl << std::endl; }
修改后代码
void printArrInt(int arr[], int len) { int max = findMaxValue(arr, len); std::string bars[len]; for (int i = 0; i < len; i++) { for (int j = 0; j < arr[i]; j++) { bars[i].append("@"); } for (int j = 0; j < (max - arr[i]); j++) { bars[i].append(" "); } } for (int i = max; i > 0; i--) { for (int j = 0; j < len; j++) { std::cout << bars[j][i]; } std::cout << std::endl; } std::cout << std::endl << std::endl; }
核心问题
- 变长数组(VLA)的未定义行为:
std::string bars[len];是C风格变长数组,C++标准并未支持该特性,仅部分编译器提供扩展支持。这种方式分配的栈内存管理不稳定,多次调用时易出现内存溢出或数据覆盖。 - 数组越界访问:修改后的循环中
for (int i = max; i > 0; i--),当i等于max时,访问bars[j][i]会超出字符串的有效索引范围(字符串长度为max,有效索引是0到max-1),属于未定义行为,会破坏内存中的其他数据,导致后续调用异常。
解决办法
- 用
std::vector<std::string>替代变长数组,符合C++标准,确保内存管理安全。 - 修正循环索引,从
max-1开始递减到0,避免越界访问。
修正后的代码
#include <vector> #include <string> #include <iostream> // 实现findMaxValue函数示例 int findMaxValue(int arr[], int len) { int max = arr[0]; for (int i = 1; i < len; i++) { if (arr[i] > max) max = arr[i]; } return max; } void printArrInt(int arr[], int len) { int max = findMaxValue(arr, len); // 用vector替代变长数组 std::vector<std::string> bars(len); for (int i = 0; i < len; i++) { bars[i].append(arr[i], '@'); bars[i].append(max - arr[i], ' '); } // 从max-1开始递减,避免越界 for (int i = max - 1; i >= 0; i--) { for (int j = 0; j < len; j++) { std::cout << bars[j][i]; } std::cout << std::endl; } std::cout << "\n\n"; }
内容的提问来源于stack exchange,提问作者Daniele
相关产品推荐
相关产品推荐

