【问题标题】:ppm double subscripted array errorppm 双下标数组错误
【发布时间】:2014-06-05 20:01:34
【问题描述】:

我目前正在为我的学校项目制作一个程序。它应该读取 ppm 图像并返回渐变作为输出。但我在处理 420 x 360 等大图像时遇到问题。它适用于两侧低于 300 像素的图像。谁能告诉我我的代码有什么问题?谢谢。哦,它在 C 中。

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


struct imageHeader{
    char code[3];
    char startComment;
    char comment[1000];
    int width;
    int height;
    int offset;
} header;

struct imagePixel{
    int red;
    int green;
    int blue;
    int total;
};

int main(){
    FILE *image;
    FILE *imageOut;



    image = fopen("sunset.ppm", "rb");
    imageOut = fopen("output.ppm", "wb");

    fseek(image, 0, SEEK_SET);
    fseek(imageOut, 0, SEEK_SET);

    // ********* Get the right Code *************
    fgets(header.code, sizeof(header.code), image);


    if(strcmp(header.code, "P3")){
        puts("Not suitable file format!");
    }

    fputs(header.code, imageOut);
    fputs("\n", imageOut);
    //*********** SKIP THE COMMENT IF EXIST *****************
    header.startComment = fgetc(image);
    if(header.startComment = '#'){
        fgets(header.comment, sizeof(header.comment), image);
    }
    fputs(header.comment, imageOut);

    //**************** Get the Width of the picture ***************
    fscanf(image, "%d", &header.width);
    fprintf(imageOut, "%d ", header.width);

    //**************** Get the Height of the picture **************
    fscanf(image, "%d", &header.height);
    fprintf(imageOut, "%d\n", header.height);


    //***************** Get the offset color of the picture ************
    fscanf(image, "%d", &header.offset);
    fprintf(imageOut, "%d\n", header.offset);

    struct imagePixel *ptrOne;


ptrOne = (struct imagePixel*) malloc(sizeof(ptrOne) * header.height *header.width);

if (ptrOne == NULL){
    printf("Error! Run out of memory!");
    return 1;
}

struct imagePixel number[header.height][header.width];

    //**************read the image*****************
    for(int i = 0; i <= header.height - 1; i++){
        for(int j = 0; j <= header.width - 1; j++){
            fscanf(image, "%d", &number[i][j].red);
            fscanf(image, "%d", &number[i][j].green);
            fscanf(image, "%d", &number[i][j].blue);
            number[i][j].total = (0.2126 * number[i][j].red) + (0.7152 * number[i][j].green) + (0.0722 * number[i][j].blue);
            //number[i][j].total = (number[i][j].red) + (number[i][j].green) + (number[i][j].blue);
        }
    }


    for(int i = 0; i <= header.height - 1; i++){
        for(int j = 0; j <= header.width - 1; j++){
            int axisXswap = i;
            int axisYswap = j;

            for(int x = i; x <= header.height - 1; x++){
                for(int y = j; y <= header.width - 1; y++){
                    if(number[x][y].total > number[axisXswap][axisYswap].total){
                        axisXswap = x;
                        axisYswap = y;
                    }
                }
            }

            struct imagePixel temp;

            temp.red = number[i][j].red;
            temp.green = number[i][j].green;
            temp.blue = number[i][j].blue;
            temp.total = number[i][j].total;

            number[i][j].red = number[axisXswap][axisYswap].red;
            number[i][j].green = number[axisXswap][axisYswap].green;
            number[i][j].blue = number[axisXswap][axisYswap].blue;
            number[i][j].total = number[axisXswap][axisYswap].total;

            number[axisXswap][axisYswap].red = temp.red;
            number[axisXswap][axisYswap].green = temp.green;
            number[axisXswap][axisYswap].blue = temp.blue;
            number[axisXswap][axisYswap].total = temp.total;
        }
    }

    for(int i = 0; i <= header.height-1; i++){
        for(int j = 0; j <= header.width-1; j++){
            fprintf(imageOut, "%d %d %d\n", number[i][j].red, number[i][j].green, number[i][j].blue);
        }
    }



    fclose(image);
    fclose(imageOut);



}

【问题讨论】:

  • 您的 struct imagePixel number[header.height][header.width] 似乎(方式)太大而无法在堆栈上分配,即作为局部变量。使用malloc在全局内存堆中分配。
  • 让我们检查一下数字 - struct imagePixel 将是 16 个字节(使用 32 位整数),因此 16*420*360 = 2.4MB。 Windows 会将堆栈限制为 1MB,这样就可以解释问题。 (如果您说您使用的平台会有所帮助)代码中有一个 malloc,但它不正确 - 您需要从 malloc 获取返回值并将其用作指向内存块的指针。
  • @Bryan: 很好 -- 看了前半部分就累了。笔记都在那里,但还没有按正确的顺序。
  • 感谢您的回答!现在我知道问题是什么了!顺便问一下,有什么方法可以减少这种内存吗?我认为 2.4MB 对于这样一个简单的程序来说太大了。
  • 我改变了我的 malloc。我是否正确使用它?我从一个网站上举了一个例子。

标签: c arrays ppm


【解决方案1】:

您应该使用堆而不是在堆栈上分配:

struct imagePixel **number; // two dimensional array of pixels

// allocate rows
number = malloc(sizeof(struct imagePixel *) * header.height);

for (i = 0; i < header.height; ++i) {
    // allocate columns for each row
    number[0] = malloc(sizeof(struct imagePixel) * header.width);
}

// do free() in reverse as above

【讨论】:

  • 谢谢!我认为它是用 malloc 做的。但后来我的程序停止响应。是因为我使用了数字下标吗?例如数字[i][j]?
  • @user3548468 是的,错误地进行了一次分配,您确实需要为行分配一个分配,然后为每一行分配另一个分配。
猜你喜欢
  • 2013-05-16
  • 2013-04-13
  • 1970-01-01
  • 2014-02-19
  • 2011-12-13
  • 2013-01-11
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
相关资源
最近更新 更多