树莓派3裸机C编程中selectedTextColor与selectedBgColor为何无值?
问题分析与修复方案
你的代码中selectedTextColor和selectedBgColor出现无值(野指针状态),导致终端颜色无法修改,核心问题集中在变量初始化缺失、输入逻辑覆盖不全以及数组遍历存在隐患这几点。
具体问题点
- 指针未初始化:
selectedTextColor和selectedBgColor是未初始化的指针,若输入未触发赋值逻辑(比如直接回车、输入格式不符合预期),后续调用my_strcmp会访问非法内存,甚至引发程序崩溃。 - 输入逻辑未覆盖结尾场景:当前仅在遇到空格时才调用
get_color_code赋值,若用户输入-t red后直接回车(无空格),这部分输入不会被处理,变量依然处于无值状态。 - 数组遍历终止条件不安全:用
"none"作为数组终止项,若遍历到数组边界仍未匹配到"none",会导致数组越界访问。
修复后的完整代码
typedef struct color { const char *colorName; const char *textColor; const char *bgColor; } color; // 改用NULL作为数组终止标记,避免越界风险 color color_values[] = { {"black", "30", "40"}, {"red", "31", "41"}, {"green", "32", "42"}, {"yellow", "33", "43"}, {"blue", "34", "44"}, {"purple", "35", "45"}, {"cyan", "36", "46"}, {"white", "37", "47"}, {NULL, NULL, NULL} }; // 根据颜色名称获取对应的终端颜色码 const char* get_color_code(const char* color, int is_background) { // 以NULL判断数组结尾,遍历更安全 for (int i = 0; color_values[i].colorName != NULL; i++) { if (my_strcmp(color_values[i].colorName, color) == 0) { return is_background ? color_values[i].bgColor : color_values[i].textColor; } } return "0"; // 未匹配到则返回默认重置色 } void selectColor() { char colorInput[MAX_CMD_SIZE]; int inputIndex = 0; // 初始化输入索引 char command = 0; // 初始化命令标记 // 初始化指针为默认值,彻底避免野指针 const char *selectedTextColor = "0"; const char *selectedBgColor = "0"; char c; while ((c = uart_getc()) != '\n') { uart_sendc(c); // 回显输入字符到终端 if (c == ' ') { if (command == 't') { colorInput[inputIndex] = '\0'; selectedTextColor = get_color_code(colorInput, 0); } else if (command == 'b') { colorInput[inputIndex] = '\0'; selectedBgColor = get_color_code(colorInput, 1); } command = 0; inputIndex = 0; } else if (c == '-') { c = uart_getc(); // 读取后续的命令标识t/b uart_sendc(c); if (c == 't' || c == 'b') { command = c; inputIndex = 0; // 切换命令时重置输入索引 } continue; } else if (command) { // 防止缓冲区溢出,预留空间存储结束符 if (inputIndex < MAX_CMD_SIZE - 1) { colorInput[inputIndex++] = c; } } } // 循环结束后处理最后一次未完成的输入(比如直接回车的情况) if (command == 't') { colorInput[inputIndex] = '\0'; selectedTextColor = get_color_code(colorInput, 0); } else if (command == 'b') { colorInput[inputIndex] = '\0'; selectedBgColor = get_color_code(colorInput, 1); } if (my_strcmp(selectedTextColor, "0") != 0) { uart_puts("\033["); uart_puts(selectedTextColor); uart_puts("m"); } if (my_strcmp(selectedBgColor, "0") != 0) { uart_puts("\033["); uart_puts(selectedBgColor); uart_puts("m"); } }
关键修复说明
- 变量初始化:将
selectedTextColor、selectedBgColor初始化为默认重置色"0",inputIndex和command也设置初始值,彻底消除野指针风险。 - 补充结尾输入处理:在
while循环结束后,检查是否存在未处理的命令,对最后一次输入进行赋值,覆盖用户直接回车的场景。 - 安全遍历数组:把数组终止项改为
{NULL, NULL, NULL},遍历用color_values[i].colorName != NULL判断,避免数组越界访问。 - 缓冲区溢出防护:写入
colorInput时判断索引是否小于缓冲区最大容量减一,防止溢出破坏内存。
内容的提问来源于stack exchange,提问作者L.T.A
相关产品推荐
相关产品推荐

