将编辑框缓冲区转为以%结尾的字符串数组时触发访问违例
问题排查:C语言字符串分割时的访问违例错误
问题场景
需要将编辑框文本转换为一组以%结尾的字符串,实现代码及运行错误如下:
原实现代码
void Converter(HWND hwnd) { int Length = GetWindowTextLength(hEdit) + 1; LPSTR data = (LPSTR)malloc(Length); char set[500][11]; GetWindowTextA(hEdit, data, Length); int x = 0, y = 0; char record[10]; for (int i = 0; i < Length, x<500; i++) { if(data[i]!= '\0' ) { record[y] = data[i]; y++; } else if(data[i] == '%') { strcpy(set[x], record); x++; y = 0; } } free(data); }
运行错误信息
在myproject.exe中的0x00007FF684C91F9B位置触发异常:0xC0000005: 在位置0x000000CBFC8D5DAF读取时发生访问违例。
问题原因
- 数组越界无限制:
record是长度为10的数组,循环中未限制y的最大值,当连续读取超过9个字符时,会写入record的越界位置,破坏栈内存引发错误。 - 循环条件逻辑错误:
for循环用逗号表达式i < Length, x<500,实际仅判断x<500,忽略i < Length,导致i超出data长度后访问非法内存。 - 判断顺序颠倒:先判断
data[i] != '\0',再判断data[i] == '%',但%不属于'\0',导致处理分隔符的分支永远无法触发,record持续写入直到越界。 - 字符串无终止符:
strcpy要求源字符串以'\0'结尾,但record未手动添加终止符,strcpy会读取内存中随机位置的'\0',引发非法访问。
解决办法
修正后的代码如下:
void Converter(HWND hwnd) { int Length = GetWindowTextLength(hEdit) + 1; LPSTR data = (LPSTR)malloc(Length); if (data == NULL) { // 新增内存分配失败判断 return; } char set[500][11]; // 每个元素预留1位存终止符 GetWindowTextA(hEdit, data, Length); int x = 0, y = 0; char record[11]; // 扩容为11位,预留终止符位置 // 修正循环条件,同时限制i和x的范围 for (int i = 0; i < Length && x < 500; i++) { if (data[i] == '%') { // 优先判断分隔符 if (y > 0) { // 避免空字符串存入 record[y] = '\0'; // 手动添加字符串终止符 strcpy(set[x], record); x++; y = 0; } } else if (data[i] != '\0' && y < 10) { // 限制y的最大值,防止越界 record[y] = data[i]; y++; } } free(data); }
关键修正点
- 扩容
record为11位,同时限制y < 10,避免数组越界。 - 调换判断顺序,先处理
%分隔符,再处理普通字符。 - 用
&&替代逗号表达式,同时限制i和x的范围,避免访问非法内存。 - 复制前给
record添加'\0'终止符,保证strcpy操作安全。 - 新增内存分配失败的判断,避免空指针操作。
内容的提问来源于stack exchange,提问作者Pablo_76
相关产品推荐
相关产品推荐

