scanf函数输出异常及stack smashing错误排查求助
问题分析与解决方案:scanf分离数字与单位时的异常输出及栈溢出问题
核心问题原因
你的代码存在两个致命问题,直接引发了输出异常和stack smashing detected错误:
- 缓冲区溢出:
char wunit[] = ""和char hunit[] = ""这样的定义,只会创建长度为1的字符数组(仅能存储字符串终止符\0)。当scanf("%d%s")读取单位字符串时,输入的单位(比如lb、kg)长度超过数组容量,会越界写入栈内存,破坏相邻变量的存储(比如height的值被覆盖为0),同时触发系统的栈溢出保护机制,抛出stack smashing detected错误。 - 输出异常的本质:缓冲区溢出后栈内数据被篡改,比如输入
30kg时,wunit越界写入会覆盖height的内存空间,导致height变成0;同时wunit自身的存储也会因为溢出变得混乱,出现只显示t、m这类截断字符的情况。
你第二次尝试替换字符串的代码,本质问题未解决——wunit和hunit还是长度为1的数组,缓冲区溢出依然存在,所以数字被覆盖的问题并未消失。
解决方案
1. 给单位数组分配足够空间
直接定义长度足够的字符数组,比如给每个单位数组分配10个字符的空间(足够容纳绝大多数常见单位):
#include <stdio.h> #include <string.h> int main(){ int weight = 0; int height = 0; // 定义足够长度的字符数组存储单位 char wunit[10] = ""; char hunit[10] = ""; printf("Enter the body weight: "); // 添加长度限制,进一步防止溢出 scanf("%d%9s", &weight, wunit); printf("Enter the height: "); scanf("%d%9s", &height, hunit); printf("%d,%s,%d,%s\n", weight, wunit, height, hunit); return 0; }
2. 关键修改说明
char wunit[10] = "":给单位字符串分配了9个有效字符空间+1个终止符空间,足够存储常见单位。scanf("%d%9s"):%9s限制了读取的字符串长度最多为9,即使输入超长的单位,也不会溢出数组,避免破坏栈内存。
3. 针对替换单位需求的修正代码示例
如果需要替换特定单位,确保数组空间足够后再处理:
#include <stdio.h> #include <string.h> int main(){ int weight = 0; int height= 0; char wunit[10] = ""; char hunit[10] = ""; char wunit2[] = "lb"; char dummy[] = "t"; printf("Enter the body weight: "); scanf("%d%9s", &weight, wunit); printf("Enter the height: "); scanf("%d%9s", &height, hunit); if (strcmp(wunit, dummy) == 0){ printf("%d,%s,%d,%s\n", weight, wunit2, height, hunit); } else { printf("%d,%s,%d,%s\n", weight, wunit, height, hunit); } return 0; }
内容的提问来源于stack exchange,提问作者Wolfking
相关产品推荐
相关产品推荐

