c - 尝试编写修改后的结构时出现分段错误
c - Segmentation fault when trying to write a modified structure
这是一个旨在处理 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()
),确实不需要。
这是一个旨在处理 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()
),确实不需要。