我的程序在 windows(gcc) 中给出了正确的输出,但在 Linux(gcc) 中它导致了分段错误

My program gives the correct output in windows(gcc) but in Linux(gcc) it leads to segmentation fault

这个程序是求一个NFA所有状态的epsilon闭包。当我使用 gcc 和 运行 编译它时,我已经使用堆栈来获得这个 done.The 程序给出正确的输出 Windows 10(命令提示符)。但是,当我使用相同的编译器编译并在 Linux 中 运行 时,它会导致分段错误。我为此使用了任何动态内存分配。

我尝试使用 gdb 进行调试,但未能找到问题所在。显示 t运行sitions 矩阵时,在 printf("\n") 后检测到分段错误。 这对有人能找到错误很有帮助。提前致谢。

从文件中读取输入:nfa.txt。

//states
q0 q1 q2
//input_symbols 
0 1
//start_state       
q0
//final_state       
q2      
//transitions of the form : intial_state  input  final_state
q0 0 q0     
q0 e q1
q1 1 q1     
q1 e q2
q2 2 q2

输出结果如下:

232表示null t运行sition(Φ) 和-1 for ε.

States:
q0
q1
q2
Transitions read
232  0    1    2    -1
0    0    232  232   1
1    232  1    232   2
2    232  232  2     232

e-closure(0) : 0 1 2
e-closure(1) : 1 2
e-closure(2) : 2

请耐心等待,因为这是一个相当长的程序。

#include <stdio.h>     
#include <string.h>     //REMEMBER ME WHILE I'M GONE 
#include <errno.h>
#include <stdlib.h>

FILE *file;
int  numberOfStates = 0;
int  flag = 0;
int  states[20];

int  j = 0;
int  i = 0;
int  k = 0;

char a[20];

int  transitions[4][5];
int  visited[10];

int  MAXSIZE = 8;       
int  stack[8];     
int  top = -1;            

int isempty()
{
   if(top == -1)
      return 1;
   else
      return 0;
}

int isfull()
{
   if(top == MAXSIZE)
      return 1;
   else
      return 0;
}

int pop() 
{
   int data;

   if(!isempty()) {
      data = stack[top];
      top = top - 1;   
      return data;
   }
   else
         printf("Could not retrieve data, Stack is empty.\n");
 }


int push(int data) {

   if(!isfull()) {
      top = top + 1;   
      stack[top] = data;
   }
   else 
      printf("Could not insert data, Stack is full.\n");
}

int IsVisited(int edge)
{
    for(int i = 0; i < 10; i++)
        if(visited[edge] == 1)
            return 1;

    return 0;
}

void epsilon_closure(int state)
{
    int  e_closure[10];


    for(int i = 0; i < 10; i++ )
    {   e_closure[i] = -1;
        visited[i] = 0;
    }

    push(state);
    visited[state] = 1;

    while(top != -1)
    {
        int u = pop();

        j = 1;
        while(j < 5)
        {
            //if there is an epsilon transition from the state 'u' to 'v'
            if(transitions[j][0] == u && transitions[j][4] != 232) //ASCII of Φ = 232
            {
                if(! IsVisited(transitions[j][4]))
                {
                    visited[transitions[j][4]] = 1;
                    push(transitions[j][4]);
                }

            }
            j++;
        }
    }

    j = 0;
    for(int edge = 0; edge < 10; edge++)
    {
        if(visited[edge] == 1)
            e_closure[j++] = edge;
    }
    printf("e-closure(%d) : ",state);
    for (i = 0; e_closure[i] != -1; ++i)
        printf("%d ", e_closure[i]);
    printf("\n");
} 

int main()
{
    file = fopen("nfa.txt","r");

    if (file == NULL) {
        perror("fopen");
        return -1;
    }


    //Reading the states 
    while(!feof(file))
    {
        fscanf(file,"%s",a);
        if(strcmp("//states",a) == 0)
            flag = 1;
        else if(strcmp("//input_symbols",a) == 0)
            break;
        if (flag == 1 && a[0] != '/')
        {
            states[i++] = a[1] - '0';

        }
        numberOfStates = i; 
    }

    //Display the states of the e-NFA
    printf("\nStates : \n");
    for(i = 0; i < numberOfStates; i++ )
    {   
        printf("q%d\n",states[i]);
    }

    i = 1;
    flag = 0;
    //Reading the transition table

    for(int i = 0; i < 4; i++){
        for(int j = 0; j < 5; j++)
        {
            transitions[i][j] = 232;
        }

    }   
    while(!feof(file))
    {
        fgets(a,100,file);
        if(a[0] == '/')
        {   
            flag = 1;
        }
        if(flag == 1 && a[0] != '/')
        {   
            j = 0;
            //found a way to store the transition table in a matrix
            if(a[3] == 'e')
                transitions[(a[1] - '0') + 1][4] = a[6] - '0';

            else    
                transitions[(a[1] - '0') + 1][(a[3] - '0') + 1] = a[6] - '0';
            if(a[3] != 'e')
                transitions[0][a[3] - '0' + 1] = a[3] - '0';        //input
            else
                transitions[0][4] = -1;     // epsilon input
            transitions[(a[1] - '0') + 1][0] = a[1] - '0'; //initial state

        }
    }
    printf("\nTransitions read\n");
    for(int i = 0; i < 4; i++){
        for(int j = 0; j < 5; j++)
        {
            printf("%d\t",transitions[i][j]);
        }
        printf("\n"); //detected segmentation fault here
    }   

    //Calling e-closure for all the states  
    for(k = 0; k < numberOfStates; k++)
    {
        epsilon_closure(states[k]);
    }

    return 0;
}

这里有一个错误:

int push(int data) {

   if(!isfull()) {
      top = top + 1;   
      stack[top] = data;  
   }
   else 
      printf("Could not insert data, Stack is full.\n");  
}

如果 top == MAXSIZE-1, isfull() 将 return 为假,那么你将 top 增加到 MAXSIZE 并分配 stack[MAXSIZE] 什么是错误的边界并调用 UB。没有检查完整的源代码,我可以想象在分配后递增 top 是正确的,或者如果 top >= MAXSIZE-1[=19=,则必须将 isfull() 更改为 return true ]