我的函数是否正确地返回了指向结构的指针?

问题描述 投票:0回答:1

我有一个关于zybook的项目。而且我的代码似乎可以正常工作,因为它可以正确突出显示不同图像的边缘。但是,zybooks是自动的,并且使我的edgedetect功能失效。the description of the questionfurther information on the project这是我的两个功能的代码:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#include<limits.h>
typedef struct _image {
    int** pixels;
    int width;
    int height;
} Image;


Image* readImage(char* filename) {
    Image *pic= malloc(sizeof(Image));
    char type[3];
    int maxvalue;
    FILE *f1=NULL;
    f1= fopen(filename,"r");
        if(f1==NULL){
            printf("Unable to read image: %s\n",filename);
             return NULL;
        }
    fscanf(f1,"%s",type);
    fscanf(f1,"%d",&pic->width);
    fscanf(f1,"%d",&pic->height);
    fscanf(f1,"%d",&maxvalue);
    pic->pixels = (int **)malloc(sizeof(int *) * pic->height);
         for (int i = 0; i < pic->height; i++) {
            pic->pixels[i] = (int *)malloc(sizeof(int) * pic->width);
         }
     for (int i = 0; i < pic->height; i++) {
        for (int j = 0; j < pic->width; j++) {
           fscanf(f1,"%d",&pic->pixels[i][j]);
        }

    }
    fclose(f1);
  return pic;


}

Image* edgeDetect(Image* img, int threshold) {
    Image *edges;
    edges=malloc(sizeof(Image));
        edges->pixels = (int **)malloc(sizeof(int *) * img->height);
            for (int i = 0; i < img->height; i++) {
                edges->pixels[i] = (int *)malloc(sizeof(int) * img->width);
            }
    edges->height = img->height;
    edges->width = img->width;
     for (int i = 0; i < img->height; i++) {
        for (int j = 0; j < img->width; j++) {
            edges->pixels[i][j]=0;
        }
     }
     for(int i=0; i< edges->height;i++){
         for(int j=0; j<edges->width; j++){
             if( i > 0 && i< (edges->height-1) && j>0 && j<(edges->width-1) ){
                if(abs(img->pixels[i][j] - img->pixels[i][j+1]) > threshold || abs(img->pixels[i][j] - img->pixels[i-1][j]) > threshold)
                     edges->pixels[i][j]=255;
             }
            }
         }
    return edges;
}

int saveImage(char* filename, Image* img) {
   FILE* f1= NULL;
    f1= fopen(filename,"w");
    if(f1==NULL){
        printf("Unable to write image: %s\n",filename);
    return 1;
    }
    fprintf(f1,"P2\n");
    fprintf(f1,"%d %d\n",img->width,img->height);
    fprintf(f1,"255\n");
    for (int i = 0; i < img->height; i++) {
        for (int j = 0; j < img->width; j++) {
           fprintf(f1,"%d ",img->pixels[i][j]);
        }
        fprintf(f1,"\n");
    }
        fclose(f1);
        return 0;
}

void freeImage(Image* img) {
    for (int i = 0; i < img->height; i++) {
         free(img->pixels[i]);
}
free(img->pixels);
free(img);
}

int main(int argc, char** argv) {
    if( argc !=4){
         printf("Usage: ./a.out input.pgm output.pgm threshold\n");
    return 1;
    }
    int threshold= atoi(argv[3]);
    Image *data;
    data=readImage(argv[1]);
    if (data==NULL)
        return 1;
     Image *edge;
    edge= edgeDetect(data,threshold);
    freeImage(data);
    int result= saveImage(argv[2],edge);
    if (result==1)
        return 1;
    freeImage(edge);


    return 0;
}

任何技巧都会有所帮助。我知道代码可能会令人困惑,因为它可能不遵循标准格式,但这实际上是我的第一个编码类。

c multidimensional-array struct function-pointers
1个回答
0
投票

关于:

Image *pic= malloc(sizeof(Image)); 

始终检查(!= NULL)返回值以确保操作成功。如果不成功,请致电

perror( "your error message" );

将错误消息和系统认为发生错误的文本原因输出到stderr

关于:

printf("Unable to read image: %s\n",filename); 

错误消息应输出到stderr,而不是stdout。建议使用:

fprintf( stderr, "Unable to read image: %s\n %s\n", filename, strerror( errno ) );

[当调用scanf()系列的任何功能时,例如fscanf(),请始终检查返回的值(而不是参数值)以确保操作成功。注意:该函数系列返回成功的“输入格式转换”说明符的数量。

关于:

fscanf(f1,"%s",type); 
  1. 返回的任何非1的值都表示发生了错误。
  2. [使用%s和/或%[...]时,始终包含MAX CHARACTERS小于输入缓冲区长度的修饰符避免任何缓冲区溢出和未定义的行为,因为那些“输入格式转换”说明符总是将NUL字节附加到输入。

关于:

pic->pixels = (int **)malloc(sizeof(int *) * pic->height);

在C中,返回的类型为void*,可以将其分配给任何指针。强制转换只会使代码混乱。建议删除演员表。

为了便于阅读和理解:

  1. 单独的代码块:forifelsewhiledo...whileswitchcase default应该通过单个空白行分隔。
  2. 始终缩进代码。在每个大括号“ {”之后缩进。在每个右大括号'}'之前不要缩进。建议每个缩进级别是4个空格

  3. 插入适当的水平空间:括号内,在括号内,在括号内,在逗号后,在分号之后,围绕C运算符

函数:malloc()期望参数的类型为size_t。像这样的语句:

edges->pixels = (int **)malloc(sizeof(int *) * img->height);

作为参数的一部分传递了int。 (即img->height)会导致intsize_t之间的隐式转换,“通常”无害,但仍然是危险的转换。

© www.soinside.com 2019 - 2024. All rights reserved.