在终端中进行编译时,我不断收到错误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;
}
答案 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]
是否已成功分配。