c - 尝试写入修改后的结构时出现段错误

标签 c pointers struct segmentation-fault memcpy

这是一个旨在处理 ppm 图像文件的程序。

尝试修改结构然后将其写入新文件时遇到编译错误。

这是全局结构(在 ppmIO.c 和 ppmIO.h 中声明):

ppmIO.c:

struct Image *instance;

ppmIO.h:

struct Image
{
  int width;
  int height;
  unsigned char *data;
};

extern struct Image *instance;

这是我的 imageManip.h 文件:

#include <ppmIO.h>

void ImageInvert(struct Image **toInvert);

void ImageSwap(struct Image **toSwap);

这些是我的 imageManip.c 文件的相关部分:

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <ppmIO.h>
#include <imageManip.h>

void ImageInvert(struct Image **toInvert) {


  int i;
  int pix = (*toInvert->width) * (*toInvert->height);

  *toInvert = realloc(*toInvert, 2* sizeof *instance);

  for (i = 0; i < pix; i++)
    {
      *(toInvert)->data = ((unsigned char)255 - *(toInvert)->data));
      *(toInvert)->data = ((unsigned char)255 - *(toInvert)->data++));
      *(toInvert)->data = ((unsigned char)255 - *(toInvert)->data++));
    }

}

void ImageSwap(struct Image **toSwap) {

  int i;
  int pix = (*toSwap)->width * (*toSwap)->height;

  *toSwap = realloc(*toSwap, 2* sizeof *instance);

  unsigned char what = (*toSwap)->data;

  for (i = 0; i < pix-1; i++)
    {
      (*toSwap)->data = (*toSwap)->data++;
      (*toSwap)->data = (*toSwap)->data++;
      (*toSwap)->data = what;
      what = (*toSwap)->data++;
    }

}

这是ImageWrite方法,用于将修改后的图像结构写入文件:

void ImageWrite(char *filename)
{
  int num;
  printf("%d", num);
  int size = (instance->width) * (instance->height) * 3;


  FILE *fp = fopen(filename, "w");

  if (!fp) die("cannot open file for writing\n");

  fprintf(fp, "P6\n%d %d\n%d\n", instance->width, instance->height, 255);

  num = fwrite((void *) instance->data, 1, (size_t) size, fp);

  if (num != size) die("cannot write image data to file\n");

  fclose(fp);
}

这就是我从 main 调用修改函数的方式:

  ImageInvert(&instance);
  ImageSwap(&instance);
  ImageWrite(first); //where first is a filename

这是 gdb 报告的段错误:

Program received signal SIGSEGV, Segmentation fault.
__mempcpy_sse2 () at ../sysdeps/x86_64/memcpy.S:166
166 ../sysdeps/x86_64/memcpy.S: No such file or directory.

有人建议,在我的修改函数(ImageInvert和ImageSwap)中,我不断改变指针,而不是指向的数据。如果是这样,我怎样才能改变指向的数据而不仅仅是指针?

最佳答案

正如 previous question 的评论中所述,ImageInvert() 的代码可以变得更加简单。

使用下标表示法:

void ImageInvert(struct Image **toInvert)
{
    struct Image *image = *toInvert;
    int n_colour_vals = (image->width * image->height) * 3;
    unsigned char *data = image->data;

    for (int i = 0; i < n_colour_vals; i++)
        data[i] = 255 - data[i];
}

使用指针:

void ImageInvert(struct Image **toInvert)
{
    struct Image *image = *toInvert;
    unsigned char *data = image->data;
    unsigned char *end = data + (image->width * image->height) * 3;

    while (data < end)
    {
        *data = 255 - *data;
        data++;
    }
}

可能可以对imageSwap()进行等效更改,尽管我不完全确定它应该做什么。上一个问题中存在的问题可能表明重新分配是一个好主意,但是(至少对于 ImageInvert()),这实际上是不需要的。

关于c - 尝试写入修改后的结构时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40093271/

相关文章:

gcc 中的编译器优化

.net - 为什么.NET 中没有 RAII?

c - 我是否以错误的方式使用结构?

c++ - 将指针分配给两个指针的按位或

struct - 如何在结构定义中初始化数组?

java - 尝试连接到 JDBC 时 Java TCP 套接字和 C TCP 套接字之间的区别

objective-c - 将实例方法作为函数指针传递给 C 库

c - 接受返回现有连接,导致段错误

c - C 中优先级 and++ 和 * 一元运算符的问题

c - 数组作为c中的参数真的是引用类型吗?