为什么我的代码在尝试将过滤器添加到输入的bmp文件时会出错?

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

我试图将一个给定的过滤器添加到一个bmp文件,但它是第一次添加过滤器数组和tempRed时的segfaulting(我发现这是使用gdb)。我以为是因为它是从数组[-1]尝试访问内存,但是因为我们从1开始,所以我不认为会是这种情况。任何帮助是极大的赞赏。提前致谢!

int edgeDect(struct HEADER *Header, struct INFOHEADER *InfoHeader, struct PIXEL **Data){
    int i = 0, j = 0;
    char filter[3][3] =
    {{0, -1, 0},
     {-1, 4, -1},
     {0, -1, 0}};
    char tempRed, tempGreen, tempBlue;

    for(i = 1; i < InfoHeader->Height - 1; i++){
            for(j = 1; j < InfoHeader->Width - 1; j++){
                    printf("The height is %d\n",i);
                    printf("The width is %d\n", j);

                    tempRed = 0;
                    tempGreen = 0;
                    tempBlue = 0;
                    //***Where seg fault occurs
                    tempRed += (filter[0][0] * Data[i-1][j-1].Red);
                    tempGreen += (filter[0][0] * Data[i-1][j-1].Green);
                    tempBlue += (filter[0][0] * Data[i-1][j-1].Blue);

                    tempRed += (filter[0][1] * Data[i-1][j].Red);
                    tempGreen += (filter[0][1] * Data[i-1][j].Green);
                    tempBlue += (filter[0][1] * Data[i-1][j].Blue);

                    tempRed += (filter[0][2] * Data[i-1][j+1].Red);
                    tempGreen += (filter[0][2] * Data[i-1][j+1].Green);
                    tempBlue += (filter[0][2] * Data[i-1][j+1].Blue);

                    tempRed += (filter[1][0] * Data[i][j-1].Red);
                    tempGreen += (filter[1][0] * Data[i][j-1].Green);
                    tempBlue += (filter[1][0] * Data[i][j-1].Blue);

                    tempRed += (filter[1][1] * Data[i][j].Red);
                    tempGreen += (filter[1][1] * Data[i][j].Green);
                    tempBlue += (filter[1][1] * Data[i][j].Blue);

                    tempRed += (filter[1][2] * Data[i][j+1].Red);
                    tempGreen += (filter[1][2] * Data[i][j+1].Green);
                    tempBlue += (filter[1][2] * Data[i][j+1].Blue);

                    tempRed += (filter[2][0] * Data[i+1][j-1].Red);
                    tempGreen += (filter[2][0] * Data[i+1][j-1].Green);
                    tempBlue += (filter[2][0] * Data [i+1][j-1].Blue);

                    tempRed += (filter[2][1] * Data[i+1][j].Red);
                    tempGreen += (filter[2][1] * Data[i+1][j].Green);
                    tempBlue += (filter[2][1] * Data[i+1][j].Blue);

                    tempRed += (filter[2][2] * Data[i+1][j+1].Red);
                    tempGreen += (filter[2][2] * Data[i+1][j+1].Green);
                    tempBlue += (filter[2][2] * Data[i+1][j+1].Blue);

                    Data[i][j].Red = tempRed;
                    Data[i][j].Green = tempGreen;
                    Data[i][j].Blue = tempBlue;
            }
    }
return 0;
}

主要:

int main(int argc, char **argv){
    struct PIXEL *ColorData;
    struct INFOHEADER InfoHeader;
    unsigned char red, green, blue;
    struct HEADER Header;

    //Checks to make sure that there are enough command line arguments
    if(argc != 6){
            printf("Not enough input arguments in the command line.\n");
            exit(1);
    }

    printf("Inputing the information into the header structs.\n");
    //Inputs the header information into the header structs
    InputHeaders(argv[1], &InfoHeader, &Header);

    printf("Inputing the RGB componets into the struct.\n");
    //Inputs the colors from the picture into is RGB comnponets
    inputColors(argv[1], &InfoHeader, &ColorData, &Header);

    //Gets the integer value for the colors from the command line
    red = atoi(argv[3]);
    green = atoi(argv[4]);
    blue = atoi(argv[5]);

    printf("Adding filter to input image\n");
    //Edge detctor: FInd the edge of the picture
    edgeDect(&Header, &InfoHeader, &ColorData);
    printf("Saving the filter into outputfilename(edge).bmp.\n");
    //Saves the edge data to the correct output file
    saveEdge(argv[2], &InfoHeader, &Header, &ColorData);

    printf("Color changing function adding the command line numbers to the current RGB values.\n");
    //Changes the color of each RGB pixel with the inputed command line values
    colorChange(&ColorData, red, green, blue, &InfoHeader);
    printf("Saving the new bmp file with the color change\n");
    //Saves te shade file to the correct output file
    saveShade(argv[2], &InfoHeader, &Header, &ColorData);


return 0;
}

存储RGB值:

int inputColors(char *filename, struct INFOHEADER *InfoHeader, struct PIXEL **Data, struct HEADER *Header){
    int i = 0, j = 0;
    FILE *inputFile;

    //Opens up the file so that it can be read from
    if((inputFile = fopen(filename, "rb")) == NULL){
            printf("Unable to open .bmp file\n");
            exit(1);
    }

    //Mallocing enough space for the 2D structures of pixels (colors)
    Data = (struct PIXEL **)malloc(InfoHeader->Height * sizeof(struct PIXEL *));
    for(i = 0; i < InfoHeader->Height; i++){
            Data[i] = (struct PIXEL *)malloc(InfoHeader->Width * sizeof(struct PIXEL));
    }

    //This goes until after we are down with the header
    fseek(inputFile, Header->Offset, SEEK_SET);

    //Inputing the data into the malloced struct
    i = 0, j = 0;
    for(i = 0; i < InfoHeader->Height; ++i){
            for(j = 0; j < InfoHeader->Width; ++j){
            //      printf("Width is %d\n", i);
            //      printf("Height is %d\n", j);
                    Data[i][j].Red = getc(inputFile);
            //      printf("The Red componet is %X\n", Data[i][j].Red);
                    Data[i][j].Green = getc(inputFile);
            //      printf("The green componet is %X\n", Data[i][j].Green);
                    Data[i][j].Blue = getc(inputFile);
            //      printf("The blue componet is %X\n", Data[i][j].Blue);
            }
    }

    fclose(inputFile);
return 0;
}
c segmentation-fault bmp
1个回答
0
投票

你分配给inputColorsData中的行将在该函数中设置Data的值。它的值不会传递给调用者(main),当你稍后尝试使用时,会使ColorData未初始化。

要传递您在inputColors中创建的2D数组,您需要将数据作为struct PIXEL ***Data传递,使用*Data = malloc进行分配,并将ColorData中的main更改为struct PIXEL **ColorData。它可以通过将该内存分配给局部变量(称为inputColors,并将参数更改为Data),并且仅在存储它时使用参数名称(struct PIXEL ***pData)来简化*pData = Data;中新分配的内存的使用。

或者,不要将Data作为参数传递。在return声明中将其传递给调用者。

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