从二进制文件加载图像像素时出现 C++ 段错误

标签 c++ file-io segmentation-fault

为了好玩而做一些 C++ 并遇到问题,当我在对图像进行一些修改后加载图像时,它会给我段错误。我觉得我错过了什么,但我不知道在哪里。

编辑 这是保存和加载函数的代码(假设包含所有必要的头文件):

    int Image::save(const char* filename)
    {
      if(filename == NULL)
      {
        return 1;
      }
      ///*
      ofstream outFile(filename, ios::out | ios::binary);
      if (!outFile)
      {
        return 1;
      }
      outFile.write(reinterpret_cast<char*>(&cols), sizeof(unsigned int));
      outFile.write(reinterpret_cast<char*>(&rows), sizeof(unsigned int));
      outFile.write(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows);
      outFile.close();
      return 0;
    }

    int Image::load(const char* filename)
    {
      if(filename == NULL)
      {
        return 1;
      }
      ///*
      ifstream inFile(filename, ios::in | ios::binary);
      if (!inFile)
      {
        return 1;
      }
      **//feels like the segmentation fault is happening here**

      inFile.read(reinterpret_cast<char*>(&cols), sizeof(unsigned int));
      inFile.read(reinterpret_cast<char*>(&rows), sizeof(unsigned int));
      inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows);
      inFile.close();
      return 0;
    }

编辑 这是我正在使用的头文件:

class Image {

public:
  unsigned int cols;
  unsigned int rows;
  uint8_t* pixels;

...

/* Saves the image in the file filename. In a format that can be
     loaded by load().  Returns 0 on success, else a non-zero error
     code. */
  int save( const char* filename );

  /* Load an image from the file filename, replacing the current
     image size and data. The file is in a format that was saved by
     save().  Returns 0 success, else a non-zero error code . */
  int load( const char* filename );
};

最佳答案

当您使用 ios::ate 打开文件时,您在尝试读取文件之前将文件指针移动到文件末尾。你想从文件的开头读取,所以 ios::ate 应该被删除。

此外,您正在循环读取,而不是循环写入。你的 while 应该是一个 if,或者只是被删除。

Also read 不会调整您的指针(或者不应该...请参阅我的下一点),而只是将数据读入您指向的位置。所以 NULL 检查(如果 pixels==NULL)是无意义的。

此外,您不应该对像素 使用地址运算符 (&)。 pixels 已经是一个指针,您对该变量的读写都应该删除 &,如下所示:

inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows);

您可能会发现这有帮助: http://boredzo.org/pointers/

编辑:

    inFile.read(reinterpret_cast<char*>(&cols), sizeof(unsigned int));
    inFile.read(reinterpret_cast<char*>(&rows), sizeof(unsigned int));
    resize(cols, rows, 0);
    inFile.read(reinterpret_cast<char*>(pixels), sizeof(uint8_t) * cols * rows);

您的 resize() 需要确保指针在尝试删除它之前不为 NULL,并且您可能应该将 fill() 设为一个单独的函数。

但至少做

int Image::resize(unsigned int width,  unsigned int height, uint8_t fillcolor)
{
  if (pixels != NULL)
      delete[] pixels;
  ...

关于从二进制文件加载图像像素时出现 C++ 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45492721/

相关文章:

C++ SFML - 如何制作弹跳 Sprite ?

c++ - 将证书和 png 加载到 char*

c - 使用无缓冲 IO 例程询问和读取用户输入

c++ - 当我写入超出数组末尾时,为什么不会出现段错误?

c++ - 在 Meson 中,我是否可以避免不断地从源代码跳转到构建目录并返回?

c++ - 在 C++ 中打印总和为目标的子集

c++ - 在运行时加载的共享库中使用动态分配的对象时出现段错误

c - fgetc 无法加载文件的最后一个字符

c - 为什么我的指针数组在 C 中有段错误?

c++ - 段错误 ||访问违规写入位置