C语言函数返回ASCII控制码对应字符串时出现访问违例求助
问题排查与修复方案
核心错误原因
变量作用域与重名冲突:
函数中声明的static char** contrs = NULL;是静态指针,但在if(first)块内又定义了同名局部数组char *contrs[35],局部数组会覆盖静态指针的作用域。当if块执行完毕后,局部数组的栈内存被释放,静态指针contrs仍为NULL,后续访问contrs[c]时触发空指针访问违例。控制码名称索引错误:
原数组中索引16的位置错误填写为DEL,实际对应控制码16的是DLE(Data Link Escape),DEL仅对应控制码127。可打印字符遗漏终止符:
处理33-126可打印字符时,未显式添加字符串终止符'\0',可能导致后续输出乱码。
修复后的完整代码
主函数(补充内存释放)
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> typedef unsigned char BYTE; void showASCIIContrChars(const char, char[]); int main(void) { int numEls = 500; char conChars[4] = { '\0', '\0','\0', '\0' }; BYTE* bufA = calloc(numEls, 1); for (int i = 0; i < 500; i++) { bufA[i] = i; showASCIIContrChars(bufA[i], conChars); printf("%3d %s\n", i, conChars); } free(bufA); // 释放动态分配的内存,避免泄漏 }
修复后的showASCIIContrChars函数
void showASCIIContrChars(const char c, char str[]) { // 用静态数组直接存储控制码名称,规避作用域问题 static const char* contrs[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS ", "HT ", "LF ", "VT ", "FF ", "CR ", "SO ", "SI ", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM ", "SUB", "ESC", "FS ", "GS ", "RS ", "US ", "SPA", "DEL", "INV" }; memset(str, 0, 4); // 清空输出缓冲区,避免残留数据干扰 // 转为unsigned char处理,避免char默认有符号导致的负数误判 unsigned char uc = (unsigned char)c; if (uc > 127) { strcpy_s(str, 4, contrs[34]); } else if (uc < 33) { strcpy_s(str, 4, contrs[uc]); } else if (uc == 127) { strcpy_s(str, 4, contrs[33]); } else { str[0] = c; str[1] = ' '; str[2] = ' '; str[3] = '\0'; // 显式添加字符串终止符 } }
额外优化说明
- 类型安全处理:将
char转为unsigned char判断范围,避免因char默认有符号导致的负数误判(如0x80会被解析为-128,触发错误分支)。 - 缓冲区初始化:用
memset清空输出缓冲区,确保每次输出不受之前残留数据影响。
内容的提问来源于stack exchange,提问作者csharp
相关产品推荐
相关产品推荐

