You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改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; 
}

根本原因

  1. 图案字符串长度不一致引发内存越界读取
    sl工具的列车滚动效果依赖于d51数组中所有图案行的长度完全一致。原D51STR2末尾的空格是刻意添加的,用来保证该行长度和其他图案行相同。当你移除这个空格后,D51STR2的长度变短。

在打印循环中,代码通过索引滚动读取d51数组的行内容,但my_mvaddstr函数会一直打印到字符串的\0终止符。由于短字符串的\0之后的内存区域刚好存储了其他图案行的内容(比如wagon部分的|字符),函数会继续读取并打印这些越界的字符。

  1. wagon打印代码的注释导致无补位覆盖
    原本wagon的coal[i]字符串会打印在列车尾部的右侧区域,相当于用空白或其他字符覆盖了越界读取可能出现的多余内容。注释掉这段代码后,没有内容覆盖这些越界字符,所以所有多余的|都直接显示在了终端上。

内容的提问来源于stack exchange,提问作者skami0_0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 02:02:31