返回函数时出现分段错误错误

时间:2017-07-06 06:25:51

标签: c segmentation-fault

所以,我正在为LC3b机器编写一个解释器。我需要编写一个函数来检查输入是否是有效的操作码。为此,我编写了如下函数:

int isOpcode(char* oput)//oput=Opcode under test
{
  FILE* isa_file = NULL;
  int i,j;
  char * line = NULL;
  size_t len = 0;
  ssize_t nread;

  //printf("Entered opcode checking function \n");
  /*convert to lower case */
  //for( i = 0; i < strlen( oput ); i++ )
  //    oput[i] = tolower( oput[i] );
  //printf("Entered opcode checking function1 \n");

  /*for modularity, using the file */
   isa_file = fopen("isa", "r");
   if(isa_file == NULL)
       printf("Error in file opening\n");
   int flag;
   while ((nread = getline(&line, &len, isa_file)) != -1)
   {
       printf("Retrieved line of length %zu :\n", nread);
       printf("%s", line);  
       //Solving the new line character problem which resulted in the improper difference of strcmp ..now it is proper...
       //char final[strlen(line)-1];
       //strcpy(final,line);
       //final[strlen(line)-1]='\0'; 
       //  printf("Entered opcode checking function2 \n");
       //  printf("%s \n",oput);
       // overwrite \n with nul-terminator
       line[strcspn(line, "\n")] = 0;
       char final[strlen(line)];
       strcpy(final,line);
       flag=strcmp(oput,final);
       printf("%s \n",oput);
       printf("flag: %d \n",flag ); 
       if(flag < 0 || flag >0)
       {
           flag=-1;
           //printf("entered 1st condition \n");
           printf("final flag: %d \n", flag);
        }
       else 
       {
           flag=1;
           //printf("entered negative \n");
           printf("final flag: %d \n", flag);
           break;
       }

   }
   printf("end of loop \n");//this is not getting printed
   fclose(isa_file);
   if (line)
       free(line);
   return flag;
}

现在,当我使用其中一个有效操作码调用该函数时,该函数会打印最终标志(= 1),然后进入分段错误。它甚至不打印循环结束语句。有人能告诉我这是什么问题吗?我尝试将部分功能部分作为单独的文件执行,看起来效果很好。

更新: 当我注释掉toLower代码时,循环语句的结尾现在被打印在屏幕上。但是,即使然后代码也会抛出一个seg错误。有趣的是,它只在最终标志设置为1时才会抛出错误。否则,它运行正常!我无法理解这个奇怪的问题!

2 个答案:

答案 0 :(得分:1)

发表评论后我可以说:

strlen已经为您提供了阅读字符-1的长度,因为nul-terminator不计算在内。此外,您无法使用strcpy来执行您需要执行的操作,因为它会将源字符串的所有字符复制到一个较小的字符串中,从而导致UB。

您可以做的是删除源字符串中的'\n',然后将其复制,如:

// overwrite \n with nul-terminator
line[strcspn(line, "\n")] = 0;
// allocate new string less by one
char final[strlen(line)+1];
// allocate new string less by one
strcpy(final,line);

答案 1 :(得分:0)

以下提议的代码:

  1. 干净地编译
  2. 不会链接,因为没有main()功能
  3. 适用所有评论
  4. 现在建议的代码:

    #include <stdio.h>  // printf(), FILE, fopen(), fclose(), perror()
    #include <string.h> // strcpy(), strchr()
    #include <stdlib.h> // malloc(), free(), exit(), EXIT_FAILURE
    #include <ctype.h>  // tolower()
    
    int isOpcode(char* oput);
    
    int isOpcode(char* oput)//oput=Opcode under test
    {
        FILE* isa_file = NULL;
        //int i;  <-- unused
        //int j;  <-- unused
    
    
    
        //printf("Entered opcode checking function \n");
        /*convert to lower case */
        for( size_t i = 0; i < strlen( oput ); i++ )
            oput[i] = (char)tolower( oput[i] );
        //printf("Entered opcode checking function1 \n");
    
        /*for modularity, using the file */
        isa_file = fopen("isa", "r");
    
        if(isa_file == NULL)
        {
            perror( "fopen to open 'isa' for read, failed" );
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        int flag;
        char * line = NULL;
        size_t len = 0;
        ssize_t nread;
    
        while ((nread = getline(&line, &len, isa_file)) != -1)
        {
           printf("Retrieved line of length %zu :\n", nread);
    
           printf("%s", line);
    
           //Solving the new line character problem which resulted in the improper difference of strcmp ..now it is proper...
           char final[ nread+1 ];
           strcpy(final, line);
    
           //  printf("Entered opcode checking function2 \n");
           //  printf("%s \n",oput);
           // overwrite \n with nul-terminator
           char *newline = NULL;
           if( NULL != (newline = strchr( final, '\n' ) ) )
               *newline = '\0';
    
           printf("%s \n",oput);
           printf("flag: %d \n",flag );
    
           strcmp(oput,final);
           switch( strcmp(oput,final) )
           {
                case -1:
                case 1:
                   flag=-1;
                   //printf("entered 1st condition \n");
                   printf("final flag: %d \n", flag);
                   break;
    
                case 0:
                   flag=1;
                   //printf("entered negative \n");
                   printf("final flag: %d \n", flag);
                   break;
    
               default:
                   break;
            }
    
            free( line );
            line = NULL;
            len = 0;
        }
    
        if( !feof( isa_file ) )
            perror( "getline failed" );
    
        printf("end of loop \n");//this is not getting printed
        fclose(isa_file);
    
    
        free(line);
    
        return flag;
    }
    

    我不确定这是否是您正在寻找的功能。