修改sl源码字符串末尾空格后控制台打印异常原因排查
sl工具修改后出现多余
|字符的原因分析 问题背景
在xfce4终端中修改sl(Steam Locomotive)工具源码时出现异常:
- 修改
sl.h中的D51STR2宏定义,移除字符串末尾的空格 - 同时注释掉D51列车wagon相关的
my_mvaddstr(y + i + dy, x + 53, coal[i]);代码 - 结果:控制台打印列车图案时,尾部出现大量多余的
|字符
关键代码对比
原宏定义:
#define D51STR2 " _D _| |_______/ \__I_I_____===__|_________| "
修改后宏定义:
#define D51STR2 " _D _| |_______/ \__I_I_____===__|_________|"
异常输出示例:
_D _| |_______/ \__I_I_____===__|_________|||||||||||||||||||||||||||||
相关核心代码
- 图案数组声明:
static char *sl[LOGOPATTERNS][LOGOHEIGHT + 1] = {{LOGO1, LOGO2, LOGO3, LOGO4, LWHL11, LWHL12, DELLN}, {LOGO1, LOGO2, LOGO3, LOGO4, LWHL21, LWHL22, DELLN}, {LOGO1, LOGO2, LOGO3, LOGO4, LWHL31, LWHL32, DELLN}, {LOGO1, LOGO2, LOGO3, LOGO4, LWHL41, LWHL42, DELLN}, {LOGO1, LOGO2, LOGO3, LOGO4, LWHL51, LWHL52, DELLN}, {LOGO1, LOGO2, LOGO3, LOGO4, LWHL61, LWHL62, DELLN}};
- 图案打印循环:
for (i = 0; i <= D51HEIGHT; ++i) { my_mvaddstr(y + i, x, d51[(D51LENGTH + x) % D51PATTERNS][i]); }
- 自定义打印函数:
int my_mvaddstr(int y, int x, char *str) { for ( ; x < 0; ++x, ++str) if (*str == '\0') return ERR; for ( ; *str != '\0'; ++str, ++x) if (mvaddch(y, x, *str) == ERR) return ERR; return OK; }
根本原因
- 图案字符串长度不一致引发内存越界读取
sl工具的列车滚动效果依赖于d51数组中所有图案行的长度完全一致。原D51STR2末尾的空格是刻意添加的,用来保证该行长度和其他图案行相同。当你移除这个空格后,D51STR2的长度变短。
在打印循环中,代码通过索引滚动读取d51数组的行内容,但my_mvaddstr函数会一直打印到字符串的\0终止符。由于短字符串的\0之后的内存区域刚好存储了其他图案行的内容(比如wagon部分的|字符),函数会继续读取并打印这些越界的字符。
- wagon打印代码的注释导致无补位覆盖
原本wagon的coal[i]字符串会打印在列车尾部的右侧区域,相当于用空白或其他字符覆盖了越界读取可能出现的多余内容。注释掉这段代码后,没有内容覆盖这些越界字符,所以所有多余的|都直接显示在了终端上。
内容的提问来源于stack exchange,提问作者skami0_0
相关产品推荐
相关产品推荐

