Thread: Segmentation Fault

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6

    Question Segmentation Fault

    Hello All,

    I've been working on a project for 3 days straight on image processing and dynamic memory allocation. However, every time I compile and run, I get a segmentation fault, the most useless message C could give me.
    I've tried to isolate the message, in this project and in a smaller, similar program in which I get the same message, but there is no consistency at all. Sometimes it'll run the printf and scanf functions, then produce the fault, but when I scatter testing printf("hi)'s all over the place, none of them show up!

    Here is the code for the smaller program:

    [tag]
    Code:
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void main()
    {
    
      unsigned char **image; /* Each pixel is a byte, best represented using
    				    unsigned char data type */
      FILE *fr; /* File pointer to open the image */
      FILE *fw; /* File pointer to write the image */
    
      int i,j;
      int rows,cols,highest_intensity; /* The pgm format header includes cols, rows, highest
    				      intensity of the image */
      int userrow, 
        usercolmn;
    
      char filename[35],
        filename2[50],
        filename3[50],
        outfile[70],
        commanda[70];
     
      
      strcpy (commanda, "djpeg -outfile image.pgm ");
    
      printf ("Please enter filename of image:\n");
      scanf ("%s", filename);
      strcpy(filename2, filename);
      strcpy(filename3, filename);
      strcat(filename, ".jpg");
      strcat(commanda, filename);
      printf ("%s", commanda);
      printf ("Enter first dimension of image:"); 
      scanf ("%d", &userrow);
      printf ("Enter second dimension of image:");
      scanf ("%d", &usercolmn);
     
      system(commanda); 
     
    
     
      fr=fopen("image.pgm","r");  /* Open the pgm file - this is the image written using above command */
    
      fscanf(fr,"P5\n%d %d\n%d\n",&cols,&rows,&highest_intensity); /* P5 represents binary format of 
    								  a  pgm file */
      
      image = (unsigned char *) calloc (userrow, sizeof(unsigned char *) ) ; 
      /* above statement allocates 'row' number of pointers that 
         point to each row of the array */
    
      /* Allocates memory for each row of image seperately,  pointed by above row-number of pointers*/
      for (i = 0; i< userrow; i++)
        image[i] = (unsigned char *) calloc (usercolmn, sizeof(unsigned char *) ) ;
     
      fread(image,1,usercolmn*userrow,fr); /* After the header, pgm has raw image */
    
      fclose(fr);
    
      /* now, lets modify the pixels.. */
    
      for (i=256;i<userrow-200;i++)
        for (j=256;j<usercolmn-200;j++)
          image[i][j]=255;
    
      strcat (filename2, "_modified.pgm");
      
      /* We will write the pgm file first */
      fw=fopen(filename2, "w");
    
      strcat (filename3, "_modified.jpg");
    
      strcpy(outfile, "cjpeg -outfile ");
      strcat(outfile, filename3);
      strcat(outfile, filename2);
    
      /* With the header first and then the image in binary */
      fprintf(fw,"P5\n%d %d\n255\n",usercolmn,userrow);
      fwrite(image,1,usercolmn,fw); 
       fclose(fw);
    
      /*The 'cjpeg' command converts the pgm file into jpeg, which can be opened by any browser*/
     
      system(outfile);
    
      for (i = 0; i< userrow; i++)
          free(image[i]);
      
    }
    [/tag]


    Now since I'm meddling with dynamic allocation, I';m sure I've done something radically dumb and simple, but I just can't see it. Can somebody help me?

    Thanks!

  2. #2
    Registered User
    Join Date
    Nov 2006
    Posts
    176
    have you run it in a debugger?

    I think you need to add some return value tests
    ie. what if fopen fails? you just proceed right on

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
      image = (unsigned char *) calloc (userrow, sizeof(unsigned char *) ) ;
    ../main.c:49: warning: assignment from incompatible pointer type
    Prefer the idiom:
    Code:
    image = calloc (userrow, sizeof *image ) ;
    FAQ > Explanations of... > Casting malloc

    And main returns an int.
    FAQ > What's the difference between... > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[])

    [edit]Further editing...
    Code:
    scanf ("%s", filename);
    User Input: Strings and Numbers [C]
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6
    what is wrong with the scanf? That seems to be where the problem is, but I coudn't figure it out

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by blaksheep423
    I've tried to isolate the message, in this project and in a smaller, similar program in which I get the same message, but there is no consistency at all. Sometimes it'll run the printf and scanf functions, then produce the fault, but when I scatter testing printf("hi)'s all over the place, none of them show up!
    Had you read the link, you might have found this:
    http://c-faq.com/stdio/fflush.html

    Quote Originally Posted by blaksheep423
    what is wrong with the scanf? That seems to be where the problem is, but I coudn't figure it out
    I have gotten a little tired of repeating the same things, even posting the same links. So I made my own. I thought it covered things fairly well. Perhaps not.

    The part about completely avoiding scanf entirely sort of precludes any discussion about "what is wrong with the scanf?"
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6
    I made the changes recommended in the links, and I still get the segmentation fault

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by blaksheep423
    I made the changes recommended in the links, and I still get the segmentation fault
    This is a good thing. With distractions out of the way, perhaps we can better focus on the problem.

    Is it possible for you to attach the input file? And post your latest code?

    Up to now I haven't tried to run this, lacking the latest code and an input file, so I've just seen what the toolchain presents. Further debugging would be best aided with these additions.

    [But sharp-eyed folks may have already seen whatever I may be overlooking in my haste.
    The easier to replicate, the easier to cure, the faster an answer.]
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    fread(image,1,usercolmn*userrow,fr); /* After the header, pgm has raw image */
    you read into image buffer as if it is continuos memory of usercolmn*userrow bytes
    It is not
    Or change your reading
    Or change your allocation technics
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6
    the previous code was only similar to the project, not the actual thing. I'm positive that the issue is in my main function, which is relatively small since i did everything thrugh other functions. Here is main():

    Code:
    int
    main(void)
    {
      unsigned char image[256][256];
    
      int cols,
        rows,
        control_var,
        i,
        m,
        max_int;
    
      char choice,
        filename[40],
        filename2[45],
        syscom[55];
    
      FILE *readfile,
        *writefile;
    
    
    
      fputs ("Please enter the filename of the image to be processed:  ", stdout);
    
      fflush (stdout);
    
    
      if (fgets (filename, sizeof filename, stdin) != NULL) {
    
        char *newline = strchr (filename, '\n');
    
        if (newline != NULL)
          *newline = '\0';
      }
    
    
      sprintf (syscom, "djpeg -outfile image.pgm %s.jpg", filename);
    
      sprintf (filename2, "%s.pgm", filename);
    
    
      readfile = fopen ("image.pgm", "r");
    
      fscanf (readfile, "P5\n%d %d\n%d\n", &cols, &rows, &max_int);
    
      for (i = 0; i< 256; ++i)
        fread (image[i], 1, 256, readfile);
    
      fclose (readfile);
    
    
      writefile = fopen ("working_image.pgm", "w");
    
      fprintf (writefile, "P5\n%d %d\n255\n", cols, rows);
      for (m = 0; m < 256; ++m)
        fwrite (image[m], 1, 256, writefile);
    
      fclose (writefile);
    
    
      do {
    
        show_instructions(filename);
    
        scanf ("%c", &choice);
    
    
        switch(choice) {
    
        case 'A':
        case 'a':
    
          mean_filter();
          control_var = 0;
          break;
    
        case 'B':
        case 'b':
    
          median_filter();
          control_var = 0;
          break;
    
        case 'C':
        case 'c':
    
          upsample();
          control_var = 0;
          break;
    
        case 'D':
        case 'd':
    
          downsample();
          control_var = 0;
          break;
    
        case 'E':
        case 'e':
    
          histogram();
          control_var = 0;
          break;
    
        case 'F':
        case 'f':
    
          system ("cjpeg -outfile histogram.jpg histogram.pgm");
          system ("xv histogram.jpg &");
          control_var = 0;
          break;
    
        case 'G':
        case 'g':
    
          threshold();
          control_var = 0;
          break;
    
        case 'H':
        case 'h':
    
          system ("cjpeg -outfile working_image.jpg working_image.pgm");
          system ("xv working_image.jpg &");
    
          control_var = 0;
          break;
    
        case 'Q':
        case 'q':
    
          printf ("Thank you for using the Image Processor!\n");
          printf ("Have a good day!\n\n");
          control_var = 99;
          break;
    
        }
      } while (control_var != 99);
    
      return(0);
    }

    I still can't see an issue, but this my first semester of any coding experience, so I'm sure its something stupid that I havent trained myself to look for.

    input file can be found here:
    http://www.udel.edu/CIS/105/chandrak...y256/eight.jpg
    Last edited by blaksheep423; 12-07-2006 at 12:19 AM.

  10. #10
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6
    I worked that part out. As i thought, it was a dumb mistake. However, I'm having segmentation faults in other parts of the program too, specifically the mean and median filtering functions. Here's the mean function:

    Code:
    void
    mean_filter(void)
    {
    
      unsigned char **readimage,
        **writeimage;
    
      FILE *fr1,
        *fw1;
    
      int i,
        j,
        k,
        l,
        m,
        rows,
        cols,
        mean,
        sum,
        max_int;
    
    
    
      fr1 = fopen ("working_image.pgm", "r");
    
      fscanf (fr1, "P5\n%d %d\n%d\n", &cols, &rows, &max_int);
    
    
      readimage = (unsigned char *) calloc (rows, sizeof(unsigned char *) ) ;
      writeimage = (unsigned char *) calloc (rows, sizeof(unsigned char *) ) ;
    
    
      for (i = 0; i< rows; ++i) {
          readimage[i] = (unsigned char *) calloc (cols, sizeof(unsigned char *) ) ;
          writeimage[i] = (unsigned char *) calloc (cols, sizeof(unsigned char *) ) ;
      }
    
    
      for (i = 0; i < rows; ++i)
          fread (readimage[i], 1, cols, fr1);
    
      fclose (fr1);
    
    
      for (i = 0; i < rows; ++i) {
        for (j = 0; j < cols; ++j) {
    
          sum = 0;
    
          if (i == rows && j == 0) {
            for (k = i - 2; k <= i; ++k) {
              for (l = j; l <= j + 2; ++l) {
    
                sum = sum + (int)readimage[k][l];
              }
            }
          }
          else if (i == rows && j != 0 && j != cols) {
            for (k = i - 2; k <= i; ++k) {
              for (l = j - 1; l <= j + 1; ++l) {
    
                sum = sum + (int)readimage[k][l];
              }
            }
          }
    ......
    ......
    ......
          else {
            for (k = i - 1; k <= i + 1; ++k) {
              for (l = j - 1; l <= j + 1; ++l) {
    
                sum = sum + (int)readimage[k][l];
              }
            }
          }
    
          mean = sum / 9;
    
          writeimage[i][j] = (int)mean;
        }
      }
    
    
      fw1 = fopen ("working_image.pgm", "w");
    
      fprintf (fw1, "P5\n%d %d\n255\n", cols, rows);
    
      for (m = 0; m < rows; ++m)
          fwrite (writeimage[m], 1, cols, fw1);
    
      fclose(fw1);
    
    
      for (i = 0; i < rows; ++i) {
        free (readimage[i]);
        free (writeimage[i]);
      }
    }

    Any thoughts?

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    if (i == rows is always false
    so we get to
    for (k = i - 1
    when i is 0 and j is 0
    you access readimage[-1][-1];
    that is obviously out of the scope
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    Registered User
    Join Date
    Dec 2006
    Location
    Newark, DE
    Posts
    6
    another dumb error. Thank you very much!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM