Access violation写入位置错误:C语言输入函数异常排查
问题分析与修复
核心错误原因
非法赋值触发内存访问违规
代码中*cstringValue = strlist;是致命错误:cstringValue是指向目标字符数组的指针,*cstringValue仅代表数组的第一个字符(1字节),而strlist作为数组名会退化为指针(x64下占8字节),强行将指针值写入单个char的内存空间,直接越界导致内存访问违规。此外strlist是函数局部数组,函数返回后内存会被释放,即便赋值逻辑正确也会产生野指针。scanf_s使用错误scanf_s("%s", &strlist)存在两处问题:strlist本身就是数组首元素地址,无需加&;scanf_s处理字符串时必须指定缓冲区大小,否则存在缓冲区溢出风险。
冗余的长度计算
手动循环计算字符串长度完全可以用标准库函数strlen替代,更简洁可靠。输入缓冲区残留问题
用户输入不符合要求时,输入缓冲区可能残留未处理的字符,导致后续scanf_s读取异常,陷入死循环。
修正后的代码
inputCString函数
#include <stdio.h> #include <string.h> #include <stdlib.h> void inputCString(char *cstringValue, int min, int max) { int strsize = 0; char strlist[50] = { '\0' }; int c; // 清理函数调用前可能残留的换行符 while ((c = getchar()) != '\n' && c != EOF); while (1) { // 正确使用scanf_s:传入数组首地址+缓冲区大小 if (scanf_s("%s", strlist, (unsigned)_countof(strlist)) != 1) { // 输入错误时清理缓冲区 while ((c = getchar()) != '\n' && c != EOF); printf("ERROR: Invalid input, please enter a string: "); continue; } strsize = strlen(strlist); if (strsize >= min && strsize <= max) { // 用安全的strcpy_s复制字符串到目标缓冲区,需指定目标缓冲区大小 strcpy_s(cstringValue, max + 1, strlist); break; } else if (min == max) { printf("ERROR: String length must be exactly %d chars: ", min); } else { printf("ERROR: String length must be between %d and %d chars: ", min, max); } // 清理当前输入的残留字符,避免影响下一次读取 while ((c = getchar()) != '\n' && c != EOF); } }
测试函数(修正输入提示)
void test06_inputCString(void) { char cstringValue[7] = { '\0' }; printf("TEST #6: - Instructions:\n" "1) Enter the word 'horse' [ENTER]\n" // 长度5,不符合要求 "2) Enter the word 'chicken' [ENTER]\n" // 长度7,不符合要求 "3) Enter the word 'Beaver' [ENTER]\n" // 长度6,符合要求 ":>"); inputCString(cstringValue, 6, 6); printf("////////////////////////////////////////\n"); printf("TEST #6 RESULT: "); printf("%s (expected result: Beaver)\n", cstringValue); printf("////////////////////////////////////////\n\n"); }
关键修复说明
- 用
strcpy_s替代非法赋值:安全复制字符串到目标缓冲区,同时指定缓冲区大小(max+1是为了预留字符串结束符\0的位置); - 修正
scanf_s参数:添加缓冲区大小,避免缓冲区溢出; - 增加输入缓冲区清理逻辑:防止错误输入导致的死循环;
- 替换手动长度计算为
strlen:简化代码同时提升可靠性。
内容的提问来源于stack exchange,提问作者Seagull Sea
相关产品推荐
相关产品推荐

