使用switch case菜单向栈压入元素时触发Segmentation Fault问题排查
问题:char类型接收菜单选择触发Segmentation Fault的原因分析
问题背景
在数据结构课程作业中,实现带switch case菜单的动态分配循环栈时,遇到以下问题:
- 使用
char类型变量接收菜单选择时,执行push函数的a[top] = e;语句总会触发Segmentation Fault - 改用
int类型变量接收菜单选择则运行正常 - 需求是支持输入任意按键退出程序,而
int类型仅支持整数输入,因此想明确段错误的触发原因
相关代码如下:
#include<stdio.h> #include<stdlib.h> int top = -1 ; int n ; int main() { void push(int*,int) ; int pop(int*) ; void display(int*) ; printf("Enter no. of elements: ") ; scanf("%d",&n) ; int* a = (int*)malloc(n*sizeof(int)) ; char c ; while(1) { printf("Enter 1. to push.\nEnter 2. to pop.\nEnter 3. to display.\nEnter anything else to exit.\n") ; scanf("%d",&c) ; int e ; switch(c) { case 1: printf("Enter the no. to be pushed: ") ; scanf("%d",&e) ; push(a,e) ; break ; case 2: e = pop(a) ; printf("%d got popped.\n",e) ; break ; case 3: display(a) ; break ; default: exit(1) ; } } free(a) ; return 0 ; } void push(int* a,int e) { top++ ; if(top==n) { printf("Stack Overflow.\n") ; exit(1) ; } a[top] = e ; }
核心错误原因
问题出在**scanf格式符与变量类型不匹配**:
- 代码中用
scanf("%d",&c);读取菜单选择,但c是char类型(通常占1字节),而%d格式符要求写入一个int类型变量(通常占4字节) - 当
scanf执行时,会从&c指向的地址开始,连续写入4字节的数据,直接导致内存越界写入,破坏了c变量相邻的内存区域 - 比如
c和栈上的动态数组指针a相邻时,越界写入会篡改a的指针值,后续执行a[top] = e;时,实际上是在访问非法内存地址,最终触发Segmentation Fault
改用int类型变量时,%d格式符与变量大小匹配,scanf写入不会越界,内存未被破坏,程序正常运行。
解决方法(满足任意按键退出需求)
要实现任意按键退出同时避免内存越界,需修正scanf的使用方式:
- 使用
%c格式符读取char类型变量,同时处理输入缓冲区的换行符:// %c前的空格会自动跳过所有空白字符(包括换行、空格) scanf(" %c", &c); - 或者先读取输入为字符串,再提取第一个字符判断,这种方式更灵活,能处理任意输入:
char input[10]; scanf("%s", input); c = input[0];
内容的提问来源于stack exchange,提问作者M.B.
相关产品推荐
相关产品推荐

