分段故障:C终端中的11条错误消息

时间:2015-03-03 02:21:51

标签: c segmentation-fault

在终端中进行编译时,我不断收到错误Segmentation Fault:11。目标是在寄宿生的图片上制作黑眼圈,并使用命令。我的理由是因为我的文件IO而无法正常工作。我没有in& amp;输出FILE类型并更改pgmUtility中调用的两个函数,以便不调用文件并且程序运行顺利。所以我假设我需要帮助专注于我的文件IO问题。

使用的命令:

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

它使用与pgmUtility.c相关的main.c程序

这是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;

}

这是pgmUtility.c的两个函数,我认为可能是问题的原因。

#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;



}

2 个答案:

答案 0 :(得分:3)

您未正确分配header数组。它应该是:

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

两个sizeof来电中的错误类型。

你根本不需要内部j循环,你反复分配给同一个header[i]

对于C(但不是C ++),请参阅:Do I cast the result of malloc?

此外,在main()的开头,你有一个你永远不会使用或免费的额外分配:

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

你应该摆脱这个。

它与错误无关,但这是错误的:

if(header == NULL)
    return NULL;

您应该测试header[r]

为清楚起见,我建议改写:

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

为:

  fscanf(in, "%d", &array[r][c]);

答案 1 :(得分:1)

看起来(即使在正确建议的情况下更正了malloc来电之后),您也会分配header[i] COLS次。

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
  }
}

这将为每个COLS分配header[i]个号码。当我读取您的代码时,您只需为每个header[i]分配一个char数组。为此,您需要将header[i] = malloc(COLS * sizeof(char));移到for(j = 0; j < COLS; j++)循环之外:

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

您还应验证header和每个header[i]是否已成功分配。