Code::Blocks下C++控制台绘图程序调用rect()函数崩溃求助
解决控制台绘图应用调用rect()崩溃的问题
看起来你在把p5.js的绘图思路转到C++控制台应用时遇到了麻烦,我帮你排查了代码里的几个关键问题,都是导致崩溃的直接原因:
1. 首先是printarray()函数的语法混乱
你的原代码里注释和大括号完全配对错误,函数结构被破坏,这会导致编译后的程序行为异常甚至崩溃。我先把这个函数的结构修正,确保它能正确遍历grid数组并输出:
void printarray() { // 遍历网格打印每个元素 for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { if (grid[y][x] == 1) { printf("#"); } else { printf("_"); } } printf("\n"); } // 打印分隔线 for (int n=0; n<WIDTH; ++n){ printf("="); } printf("\n"); }
2. rect()函数的数组越界问题(崩溃核心原因)
你写的rect函数里有两个致命的越界问题:
- 计算
xp - xs和yp - ys会得到负数下标,比如你调用rect(2,2,3,5)时,xp-xs=2-3=-1,yp-ys=2-5=-3,C++里数组不能用负数下标访问,直接触发内存访问错误导致崩溃。 - 循环终止条件没有考虑网格边界,比如如果传入的参数让
yp+ys超过HEIGHT,或者xp+xs超过WIDTH,也会越界。
修正后的rect函数应该从左上角到右下角正确绘制矩形的四条边,避免越界:
void rect(int xp, int yp, int xs, int ys) { // 确保坐标在网格范围内(可选,但能避免越界) if (xp < 0 || xp >= WIDTH || yp < 0 || yp >= HEIGHT) return; if (xs <=0 || ys <=0) return; int right = xp + xs; int bottom = yp + ys; // 确保不超出网格边界 right = right >= WIDTH ? WIDTH-1 : right; bottom = bottom >= HEIGHT ? HEIGHT-1 : bottom; // 绘制左右竖线 for (int y = yp; y <= bottom; y++) { grid[y][xp] = 1; // 左竖线 grid[y][right] = 1; // 右竖线 } // 绘制上下横线 for (int x = xp; x <= right; x++) { grid[yp][x] = 1; // 上横线 grid[bottom][x] = 1; // 下横线 } }
这里我把矩形的参数逻辑改成:xp,yp是左上角坐标,xs是宽度(x方向长度),ys是高度(y方向长度),同时增加了边界检查,避免越界访问。
3. main()函数里的冗余调用问题
你在初始化grid的嵌套循环里每次循环都调用rect,这会重复调用3200次(80*40),完全没必要,而且会导致重复赋值。应该把rect调用放在初始化循环外面:
int main() { // 初始化网格为全0 for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { grid[y][x] = 0; } } // 调用rect绘制矩形 rect(2, 2, 3, 5); // 打印网格 printarray(); return 0; }
修复后的完整代码
#include <iostream> #include <stdio.h> #define WIDTH 80 #define HEIGHT 40 using namespace std; int grid[HEIGHT][WIDTH]; int x, y, xp, xs, yp, ys, n; int length = HEIGHT * WIDTH; void printarray() { for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { if (grid[y][x] == 1) { printf("#"); } else { printf("_"); } } printf("\n"); } for (int n=0; n<WIDTH; ++n){ printf("="); } printf("\n"); } void rect(int xp, int yp, int xs, int ys) { if (xp < 0 || xp >= WIDTH || yp < 0 || yp >= HEIGHT) return; if (xs <=0 || ys <=0) return; int right = xp + xs; int bottom = yp + ys; right = right >= WIDTH ? WIDTH-1 : right; bottom = bottom >= HEIGHT ? HEIGHT-1 : bottom; for (int y = yp; y <= bottom; y++) { grid[y][xp] = 1; grid[y][right] = 1; } for (int x = xp; x <= right; x++) { grid[yp][x] = 1; grid[bottom][x] = 1; } } int main() { for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { grid[y][x] = 0; } } rect(2, 2, 3, 5); printarray(); return 0; }
额外提示
和p5.js不同,C++的数组没有自动边界检查,所以一定要注意下标范围,任何时候访问数组都要确保下标在0到数组长度-1之间,不然很容易触发崩溃。另外全局变量尽量少用,比如x、y这些可以改成函数内的局部变量,避免意外的变量污染。
内容的提问来源于stack exchange,提问作者KoMatrich
相关产品推荐
相关产品推荐

