开发者

Can't find mistake -- 'segmentation fault' - in C

I wrote this function but can't get on the problem that gives me 'segmentation fault' msg.

Thank you for any help guys !!

/*This function extract all header files in a *.c1 file*/

void in开发者_运维问答cludes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len )
{
    int i=0;
    FILE *c2_fp , *header_fp;
    char ch, *c2_file_name,header_name[80]; /* we can assume line length 80 chars MAX*/
    char inc_name[]="include"; 
    char inc_chk[INCLUDE_LEN+1]; /*INCLUDE_LEN is defined | +1 for null*/

    /* making the c2 file name */

    c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char));
    if (c2_file_name == NULL)
    {
     printf("Out of memory !\n");
     exit(0);
    } 

    strcpy(c2_file_name , c1_file_name); 
    c2_file_name[c1_file_str_len-1] = '\0'; 
    c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

    if( !(c1_fp = fopen (c1_file_name,"r") ) )
    {
     fprintf(stderr,"\ncannot open *.c1 file !\n");
     exit(0);
    }

    if( !(c2_fp = fopen (c2_file_name,"w+") ) )
    {
     fprintf(stderr,"\ncannot open *.c2 file !\n");
     exit(0);
    }

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

    ch=fgetc(c1_fp);
    while (!feof(c1_fp))
    {
        i=0;    /*zero i */ 
        if (ch == '#') /*potential #include case*/
        {
             fgets(inc_chk, INCLUDE_LEN+1, c1_fp); /*8 places for "include" + null*/
         if(strcmp(inc_chk,inc_name)==0) /*case #include*/
         {
          ch=fgetc(c1_fp);
          while(ch==' ') /* stop when head with a '<' or '"' */
          {
           ch=fgetc(c1_fp);
          } /*while(2)*/

          ch=fgetc(c1_fp); /*start read header file name*/

          while((ch!='"') || (ch!='>')) /*until we get the end of header name*/
          {
           header_name[i] = ch;
           i++;
           ch=fgetc(c1_fp);
          }/*while(3)*/
          header_name[i]='\0';  /*close the header_name array*/


          if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
          {
               fprintf(stderr,"cannot open header file !\n");
           exit(0);
              }
          while (!feof(header_fp)) /*copy header file content to *.c2 file*/
          {
           ch=fgetc(header_fp);
           fputc(ch,c2_fp);
          }/*while(4)*/
          fclose(header_fp);
         }
                }/*frst if*/
        else
        {
         fputc(ch,c2_fp);
        }
     ch=fgetc(c1_fp); 
    }/*while(1)*/ 

fclose(c1_fp);
fclose(c2_fp);
free (c2_file_name);    
}


This code seems to contain many errors, but the most evident to me is

while((ch!='"') || (ch!='>')) /*until we get the end of header name*/

I would say that every character is either different from '"' or from '>' ... or do you know a character that can be equal to both? ;-)


I'll take a shot in the dark here and guess that the c1_file_str_len argument is the result from a strlen() function call, which does not take into account the terminating NULL character. Your call to strcpy could (would?) then fail.

If not, maybe you could provide some more help here? Tried debugging? At which line does this segfault occur?


Run your program under valgrind.


Change:

while((ch!='"') || (ch!='>'))

to:

while((ch!='"') && (ch!='>'))

You are over-running the header_name buffer as you are failing to stop at the end of the include name.


The bug is here:

while((ch!='"') || (ch!='>')) /*until we get the end of header name*/

There should be && (and) instead of || (or), because this is an endless loop. ("Repeat while character isn't " or isn't >." At least one of those two conditions is always true, so it loops until a segmentation fault occurs.)

Also, there are many other flaws in your source code. But this one definitely generates segmantetion fault.

Additional notes:

  • There should be just a single parameter in your function: the source file name
  • FILE *c1_fp should be just a local variable.
  • int c1_file_str_len should be computed using strlen(), and you must add 1, otherwise your allocation for second file name misses '\0'.
  • You should prefer return; over exit(0); and also close files and free allocated memory before exit.

Also, you should make the function recursive to let it searches for #include directives in the #included files as well. And you should support "include directories" setting - list of directories where to search .h files for.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜