图像写入功能未执行

时间:2014-05-19 05:20:08

标签: c++ memory io

我有一个在我的驱动程序中调用时不执行的功能。我通过printf语句逐行调试它,但无论我将它们放在我的函数中,我都无法显示它们中的任何一个。该功能不会产生预期的结果 - 写入图像文件。

void WriteImage(char *filename, Image &img)
{
    printf("writing\n");
    FILE *f = fopen(filename, "wb");

    if (f == NULL)
    {
        fprintf(stderr, "Can't open file %s to write.\n", filename);
        return;
    }

    fprintf(f, "P6\n");
    fprintf(f, "%d %d\n", img.GetX(), img.GetY());
    fprintf(f, "%d\n", 255);
    fwrite(img.GetData(), sizeof(PixelStruct), img.GetX() * img.GetY(), f);
    fclose(f);
}

这是从我知道有效的C函数中获取的代码,因此我不知道发生了什么。有什么想法吗?

编辑:

对于它的价值,当它被自己调用并且只有它本身时它才会执行。当我事先调用前面的ReadImage时,WriteImage不会执行。这是ReadImage:

void ReadImage(char *filename, Image &output)
{
    FILE *f = fopen(filename, "rb");
    char magicNum[128];
    int  width, height, maxval;

    if (f == 0)
    {
        fprintf(stderr, "Unable to open file %s\n", filename);
        exit(0);
    }

    fscanf(f, "%s\n%d %d\n%d\n", magicNum, &width, &height, &maxval);

    printf("Magic num = %s width = %d, height = %d, maxval = %d\n",
            magicNum, width, height, maxval); 


    if (strcmp(magicNum, "P6") != 0)
    {
        fprintf(stderr, "Unable to read from file %s, because it is not a PNM file of type P6\n", filename);
        exit(1);
    }

    output.ResetSize(width, height);
    PixelStruct *data = output.GetData();
    output = Image(width, height, data);
    fread(output.GetData(), sizeof(PixelStruct), width*height, f);
    fclose(f);

}

编辑2:主要功能。

int main(int argc, char *argv[])
{
    Image img;
    ReadImage(argv[1], img);
    printf("ReadImage called.\n");
    WriteImage(argv[2], img);
}

编辑3:参数化构造函数。

Image::Image(int width, int height, PixelStruct* data)
{
    this->x = width;
    this->y = height;
    this->data = data;
}

编辑4:图像。

struct PixelStruct
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};

class Image
{
        private:
            int x;
            int y;
            PixelStruct *data;

        public:
            Image(void); /* Default constructor */
            Image(int width, int height, PixelStruct* data); /* Parameterized constructor */
            Image(Image &); /* Copy constructor */
            void ResetSize(int width, int height);
            int GetX();
            int GetY();
            PixelStruct* GetData();
            void SetData(PixelStruct *data);
};

Image::Image(void)
{
    x = 0;
    y = 0;
    data = 0;
}
Image::Image(int width, int height, PixelStruct* data)
{
    this->x = width;
    this->y = height;
    this->data = data;
}

Image::Image(Image &img)
{
    this->x = img.x;
    this->y = img.y;
    this->data = img.data;
}

void Image::ResetSize(int width, int height)
{
    this->x = width;
    this->y = height;
}

int Image::GetX()
{
    return x;
}

int Image::GetY()
{
    return y;
}

PixelStruct* Image::GetData()
{
    return data;
}

2 个答案:

答案 0 :(得分:1)

这只是一个部分答案,因为有更好的方法来设计你的类,(也取决于你是否可以使用c ++ 11结构)但我能想到的最短路径来修复你的程序如下:

1.在构造函数中分配内存并在析构函数中释放它:

Image::Image(int width, int height)
{
    this->x = width;
    this->y = height;
    this->data = new PixelStruct[width*height];
}

Image::~Image()
{
    delete[] data;
}

2.删除默认构造函数,复制构造函数和调整大小方法

3.修改您的读取图像功能

Image* ReadImage(char *filename)
{
    .
            .
            .
            //read image size


    Image *output = new Image(width, height);
    fread(output->GetData(), sizeof(PixelStruct), width*height, f);
    fclose(f);

    return output;

}

4.将您的主要修改为:

int main(int argc, char *argv[])
{

    Image* img= ReadImage(argv[1]);
    printf("ReadImage called.\n");
    WriteImage(argv[2], *img);
}

同样,这不是推荐的方法,但它应该使您的代码无需太多修改和新概念的介绍即可运行。

答案 1 :(得分:1)

您的类在数据成员方面存在许多内存管理问题。让我从你的具体问题开始

Image img;
ReadImage(argv[1], img);

此时img的缓冲区为0。

output.ResetSize(width, height);      // Buffer is still 0
PixelStruct *data = output.GetData(); // data is 0
output = Image(width, height, data);  // data is still zero

这里有内存问题。您没有赋值运算符。在这种特殊情况下,它没有真正的效果,但从长远来看可能会杀了你。你可能应该有一个工作

 ouput.ResetSize (width, height) ;

(如下所述),没有其他陈述。

fread(output.GetData(), sizeof(PixelStruct), width*height, f); // data is still 0

我很惊讶你没有对被释放的人进行打击。

修复:

这些函数应该为数据分配一个缓冲区。

        Image(int width, int height, PixelStruct* data); 
        void ResetSize(int width, int height);

此功能

        Image(Image &); /* Copy constructor */

应该复制数据(不只是指定指针)。您需要一个具有相同功能但仍应删除任何现有数据的赋值运算符。

你应该有一个释放数据的析构函数。