C-堆栈代码无法运行



我正在做一个分配。我已经完成了代码,但是当我回头看时,我发现我错过了将分数输入有效且无效的堆栈的人。

所以我是否尝试修改代码,但是修改的代码将编译但不运行。我不知道为什么。有人能帮我吗。多谢。

/*
Question 1
This program uses an array applications.
*/
#include<stdio.h>
#include<stdlib.h>

//declare struct node as STK
struct node
{
    int top;
    int element[100];
};  
struct node *valid,*invalid;//declare two stack for valid score and invalid score

int main()
{
valid->top=-1;//create empty stack for valid score
invalid->top=-1;
int size, score[size]; //variables for array purposes
int tempMin=100, tempMax=0; //variables for lowest and highest marks
int i,total=0,validCounter=0,invalidCounter=0,countH1=0,countH2=0,countH3=0,countH4=0,countH5=0; //variables for counting purposes
float average; //variable for average
printf ("STUDENTS MARK ENTERING SESSIONn");
printf ("Enter total number of student: ");
scanf ("%d", &size);
printf("n");
/*Get Marks form User*/
printf ("Enter MID-SEMESTER Test Score:n");
for (i=0;i<size;i++)
{
    printf("Test Score #%d: ",i+1);
    scanf ("%d",&score[i]);
    if((score[i]<0) ||(score[i]>100))
    printf("Error:Invalid score entered!n");
}
printf ("nThe MID-SEMESTER Test Score");

for (i=0;i<size;i++)
{
    if ((score[i]>=0) && (score[i]<=100))
    {
        valid->element[++valid->top]=score[i];//write the score into valid stack
        printf("%d ",score[i]);
        total+=score[i];
        validCounter=validCounter+1;
        if (score[i]<=tempMin)
        {
            tempMin=score[i];
        }
        if (score[i]>=tempMax)
        {
            tempMax=score[i];
        }
    }
}
/*Print Valid Score*/
printf ("nnValid score: ");
if(valid->top==-1)
printf("Empty valid score stack");
else
{
    for(i=valid->top;i>=0;i--)
    printf("%dt",valid->element[i]);
    printf("n");
}

for (i=0;i<size;i++)
{
    if ((score[i]<0) || (score[i]>100))
    {
        invalid->element[++invalid->top]=score[i];//write the score into invalid stack
        printf("%d ",score[i]);
        invalidCounter=invalidCounter+1;
    }
}
/*Print Invalid Score*/
printf ("nInvalid score: ");
if(invalid->top==-1)
printf("Empty invalid score stack");
else
{
    for(i=invalid->top;i>=0;i--)
    printf("%dt",invalid->element[i]);
    printf("n");
}
/*Print Average Score*/
average=total/validCounter;
printf("nAverage score: %.2f", average);
/*Print Lowest Score*/
printf ("nLowest score: %d", tempMin);
/*Print Highest Score*/
printf ("nHighest score: %d", tempMax);
/*Print Histogram*/
for (i=0;i<size;i++)
{
    if ((score[i]>=80) && (score[i]<=100))
    {
        countH1=countH1+1;
    }
    else if ((score[i]>=60) && (score[i]<=79))
    {
        countH2=countH2+1;
    }
    else if ((score[i]>=50) && (score[i]<=59))
    {
        countH3=countH3+1;
    }
    else if ((score[i]>=30) && (score[i]<=49))
    {
        countH4=countH4+1;
    }
    else if ((score[i]>=0) && (score[i]<=29))
    {
        countH5=countH5+1;
    }
}
printf ("nHistogram: ");
printf ("nt[80-100]: %d", countH1);
printf ("nt[60-79]:  %d", countH2);
printf ("nt[50-59]:  %d", countH3);
printf ("nt[30-49]:  %d", countH4);
printf ("nt[0-29]:   %d", countH5);
/*Print Number of Invalid Score*/
printf("nTotal number of invalid score: %d", invalidCounter);
}

这足以使您的程序调用不确定的行为:

// 1
struct node *valid,*invalid;//declare two stack for valid score and invalid score

int main()
{
// 2
valid->top=-1;//create empty stack for valid score
invalid->top=-1;

在(1(中,您将两个指针声明为struct node,但让它们不大化。当它们具有静态存储时,编译器将默认将它们初始化为null。

在(2(中,您取消了正式UB的无效指针。

快速修复可能是:

struct node _valid, _invalid;
struct node valid = &_valid, invalid = &_invalid;

但是您应该怀疑间接是否相关...

和您在评论中被告知的其他问题:

  • int size, score[size];使用非初始化的变量大小
  • 可能是其他人...

当您想操纵指针指向的结构时,这些结构应该存在于内存中。

struct node *valid,*invalid; // Two pointers pointing to NULL
int main()
{
valid->top=-1;    //  run time error: NULL->top (dereferencing NULL)
invalid->top=-1;  //  run time error: NULL->top
//...
}

可能的解决方案,在堆或堆栈上分配内存:

struct node *valid,*invalid; // Two pointers pointing to NULL
int main()
{
    // 1.
    // dynamically allocate memory for the `struct node` structure on the heap:
    valid = malloc(sizeof(struct node)); // no need to do a cast :(struct node *)
    invalid = malloc(sizeof(struct node)); // no need to do a cast :(struct node *)
    valid->top=-1;    // OK
    invalid->top=-1;  // OK
    //...
    // 2. OR use structures allocated on the stack:
    struct node valid_node;
    struct node invalid_node;
    valid = &valid_node;        // initialize pointer to the structure
    invalid = &invalid_node;    // initialize pointer to the structure 
   //....
}

注意:我会施放malloc的结果吗?

您遇到的另一个问题是:

int size, score[size]; //variables for array purposes
scanf ("%d", &size);

size在声明int score[size];

时应具有有效的值

将代码更改为:

int size;
//..
scanf ("%d", &size);
int score[size]; //variables for array purposes

编辑,回答评论问题:

在运行时,非初始化的本地变量获得了未定义的值。当您在本地定义*valid,*invalid时,它们将在堆栈上分配。size也放在堆栈上,但现在在不同的位置!由于未初始化size,因此包含堆栈上该位置中发生的任何内容。这可能是偶然的值,即0或负值。在您的情况下,随机值不好,程序将崩溃。这称为UB(未定义的行为(。全球定义*valid, *invalid不能解决问题。只是运气。size必须以适当的值初始化以确保适当的程序行为。

相关内容

最新更新