0

While compiling in the terminal I keep getting the error Segmentation Fault: 11. The goal is to make dark circles on a picture of a boarder, ect with command. My reasoning that it isn't working if because of my File IO. I did it without the in & out FILE types and changed the two functions that are called in pgmUtility to not call in files and the program ran smoothly. So I'm assuming I need to have help focusing on the issues I have with my file IO.

Command used:

$ ./a.out -c 470 355 100 < balloons.ascii.pgm > TestImages/balloons_c100_4.pgm

It uses main.c program that relates to pgmUtility.c

This is Main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "pgmUtility.h"

#define ROWS 4
#define COLS 100

void usage(void) 
{
   printf("Usage\n");
   printf(" -h Help Dialog\n");
   printf(" -e edgeWidth < OldImageFile > NewImageFile\n");
   printf(" -c centerRow centerCol radius < OldImageFile > NewImageFile\n");
   printf(" -e edgeWidth -c radius centerRow centerCol < OldImageFile > NewImageFile\n");
   exit (8);

}


int main(int argc, char * argv[]) {

   FILE *fp;
   FILE *out;
   int i, j;
   int flag1 = 0; //-e switch (edge draw)
   int flag2 = 0; //-c switch (circle draw)
   int numRows, numCols, centerRow, centerCol, radius, edgeWidth;
   char originalImage[100], newImageFile[100];


   char **header = (char**) malloc (sizeof(char*)*4);
   int **pixels;


  //command line argument parsing
  //turn flag switches on or off

   if(argc < 3)
      usage();
   if(argc > 7)
      usage();

   for(i = 1; i < argc; i++) {

      if(strncmp(argv[i], "-e", 2) == 0) {
      //set flag on
      //get edge with values)
         if(atoi(argv[i+1]) == 0) {
            usage();
         }
         edgeWidth = atoi(argv[i+1]);
         if(argv[i+2] != NULL) {
            if(atoi(argv[i+2]) != 0) {
               usage();
            }
         }
         flag1 = 1;
      }
      if(strncmp(argv[i], "-c", 2) == 0) {
      //set flag on
      //get radius and center values
         if(atoi(argv[i+1]) == 0) {
            usage();
         }
         centerRow = atoi(argv[i+1]);
         centerCol = atoi(argv[i+2]);
         radius = atoi(argv[i+3]);
         flag2 = 1;
         strcpy(originalImage, argv[5]);
         strcpy(newImageFile, argv[6]);
         fp = fopen(originalImage, "r");
         out = fopen(newImageFile, "w");

      }
      if(strncmp(argv[i], "-h", 2) == 0) {
         usage();
      }

   }

  //allocate memory for header array
   header = (char **)malloc(ROWS * sizeof(char));
   for(i = 0; i < ROWS; i++) {
      for(j = 0; j < COLS; j++) {
         header[i] = (char *)malloc(COLS * sizeof(char *));
      }
   }

  //read pgm file
   pixels = pgmRead(header, &numRows, &numCols, fp);
   if(pixels == NULL)
      usage();

   switch(flag1) {
      case 1 :
         if(flag2 == 1) {
         //execute circle draw and edge draw
            pgmDrawCircle(pixels, numRows, numCols, centerRow, centerCol, radius, header);
            pgmDrawEdge(pixels, numRows, numCols, edgeWidth, header);
         }
         else { 
         //execute only edge draw only
            pgmDrawEdge(pixels, numRows, numCols, edgeWidth, header);
         }
         break;
      case 0 :
         if(flag2 == 1) {
         //execute circle draw
            pgmDrawCircle(pixels, numRows, numCols, centerRow, centerCol, radius, header);

         }
         break;
      default : 
         usage();
         break;
   }


  //write new pgm file
   pgmWrite((const char **)header, (const int **)pixels, numRows, numCols, out);

  //Garbage Collection
  //Fix this
  //free(pixels);
  //free(header);

   for(i = 0; i < numRows; i++) {
      int *current= pixels[i];
      free(current);
   }
   for(i = 0; i < ROWS; i++) { 
      char *current = header[i];
      free(current);
   }
   return 0;

}

This is two functions from pgmUtility.c that I think may be the cause of the issue.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "pgmUtility.h"

#define ROWS 4
#define COLS 100


// Implement or define each function prototypes listed in pgmUtility.h file.
// NOTE: You can NOT change the input, output, and argument type of the functions in pgmUtility.h
// NOTE: You can NOT change the prototype (signature) of any functions listed in pgmUtility.h

int ** pgmRead( char **header, int *numRows, int *numCols, FILE *in  ){
    int r, c;
  int **array;

  for(r = 0; r < ROWS; r++) {
    fgets(header[r], COLS, stdin);
    if(header == NULL)
      return NULL;
  }

  //sscanf parses the numRows and numCols
  sscanf(header[ROWS - 2], "%d %d", numCols, numRows);

  //read in pixel map
  array = (int **)malloc(*numRows * sizeof(int *));
  for(r = 0; r < *numRows; r++) {
    array[r] = (int *)malloc(*numCols * sizeof(int));
  }

  for(r = 0; r < *numRows; r++) {
    for(c = 0; c < *numCols; c++) {
      fscanf(in, "%d", *(array + r) + c );
    }
  }
   fclose(in);
  return array;

}


int pgmWrite( const char **header, const int **pixels, int numRows, int numCols, FILE *out ){


//iterate straight through pixels
//setup with a loop to insert a new line every "numCols" and keep printing until "numRows + 1" is reached (as soon as numRows + 1   break loop)
   int i, j;
   for(i = 0; i < 4; i++){
    //printf("%s", *header[i]);
      fprintf(out, "%c", *header[i]);

   }
    //for(i = 0; i < 4; i++)
            //fprintf(out, "*I=%d**%s**", i, header[i]);


   for(j = 0; j < numRows; j++){
      for(i = 0; i < numCols; i++)
         fprintf(out, "%d ", pixels[i][j]);
      fprintf(out, "\n");

   }
   fclose(out);
   return 0;



}
user3040301
  • 39
  • 2
  • 9
  • Use a debugger to determine where is the Segmentation Fault occurring and then repost the question. And please format your code, it is Irrespectful to pretend that someone would read your code. – Iharob Al Asimi Mar 03 '15 at 02:23
  • FYI: [Don't cast malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Mar 03 '15 at 02:23
  • @iharob I tried debugging with command lldb but it exits & doesn't let me write commands. – user3040301 Mar 03 '15 at 02:29
  • Your reason for thinking the problem is in the I/O is faulty. If you misuse pointers or write outside the bounds of an array, you get undefined behavior, and it's totally unpredictable which later code will trigger the error. Removing the I/O code doesn't mean that the problem is in the I/O, it just means that you didn't run over the landmines that the earlier heap corruption left. – Barmar Mar 03 '15 at 02:53

2 Answers2

3

You're not allocating the header arrays correctly. It should be:

header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
    header[i] = malloc(COLS * sizeof(char));
}

You had the wrong types in the two sizeof calls.

You didn't need the inner j loop at all, you were repeatedly assigning to the same header[i].

And for C (but not C++) see: Do I cast the result of malloc?

Also, at the beginning of main() you have an extra allocation that you never use or free:

char **header = (char**) malloc (sizeof(char*)*4);

You should get rid of this.

It's not related to the error, but this is wrong:

if(header == NULL)
    return NULL;

You should be testing header[r].

For clarity, I recommend rewriting:

  fscanf(in, "%d", *(array + r) + c );

as:

  fscanf(in, "%d", &array[r][c]);
Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

It appears (even after correcting the malloc call as correctly suggested), you are allocating header[i] COLS number of times.

header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
  for(j = 0; j < COLS; j++) {
     header[i] = malloc(COLS * sizeof(char));  // this happens COLS times
  }
}

That will leave COLS number of each header[i] allocated. As I read your code, you need only allocate a single char array for each header[i]. To do this, you need to move header[i] = malloc(COLS * sizeof(char)); outside the for(j = 0; j < COLS; j++) loop:

header = malloc(ROWS * sizeof(char*));
for(i = 0; i < ROWS; i++) {
    header[i] = malloc(COLS * sizeof(char));
}

You should also validate that header and each header[i] were successfully allocated.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85