尝试从 switch case 菜单将元素推入堆栈时出现分段错误

问题描述 投票:0回答:1

最近在我们的数据结构课程中,我们介绍了堆栈,并承担了在无限循环中使用 switch case 菜单实现堆栈的任务。这应该很容易,但是使用动态内存分配,我在将元素推送到堆栈中时不断遇到此段错误,这是我在 VS Code 调试器的帮助下检测到的。

这是需要注意的代码(我省略了 pop() 和 display(),因为执行永远不会到达那里):

#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 ; 
}

您可能会想:为什么在 switch case 中使用 char 变量?令我惊讶的是,当使用 int 类型作为“c”时,程序按预期运行,直到我意识到使用 char 变量不仅允许用户输入整数,还可以输入任何键来退出程序。 分段错误总是发生在最后一行:

a[top] = e ;

它提出了一个有趣的困境,打败了我。为什么 char 变量会导致段错误?两者是两个完全不相关的东西,而 int 类型却获得了免费通行证?或者是我在一段时间后回到电脑时错过了一些琐碎的事情?

c switch-statement stack
1个回答
0
投票

"%d"
告诉
scanf
期待
int
scanf("%d",&c)
向其传递
c
的地址,即
char

scanf
尝试将
int
写入您传递的地址时,它可以覆盖
c
之外的内存。这可能是您的程序用于其他目的的内存,并且可能会导致您的程序以各种方式误入歧途。

大多数编译器都会对此进行诊断。编译时启用警告并升级为错误。对于 Clang,从

-Wmost -Werror
开始。对于 GCC,从
-Wall -Werror
开始。对于 MSVC,从
/W3 /WX
开始。

© www.soinside.com 2019 - 2024. All rights reserved.