我正在尝试编写一个程序来处理 ppm 图像文件,对于最大 622x1023 左右的相对较小的文件可以正常工作,但是对于更大的文件,程序会抛出段错误。
我已将问题隔离到此函数:
void img2list(FILE *fp,int x,int y,int bd,int *resultado,long tamano){
int dimx=x,dimy=y;
int bitDepth=bd;
long numeroPixeles=(dimx*dimy*bitDepth);
int con=0;
int pixels[numeroPixeles];
while (!feof(fp)){
pixels[con]=fgetc(fp);
con++;
}
memcpy(resultado,pixels,tamano);
}
特别是:
feof(fp)
和
fgetc(fp)
我正在使用此命令编译代码: gcc main.c -o pim 我在具有 16GB RAM 的核心 i7 5820k 上运行 Ubuntu 19.04
完整代码如下:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int * getMeta(FILE *fp){
static int meta[3];
size_t len = 0;
char * line = NULL;
char delim[] = " ";
getline(&line,&len,fp);
getline(&line,&len,fp);
char *ptr1 = strtok(line, delim);
char *ptr2 = strtok(NULL, delim);
sscanf(ptr1, "%d", &meta[0]);
sscanf(ptr2, "%d", &meta[1]);
getline(&line,&len,fp);
char *ptr3 = strtok(line, delim);
sscanf(ptr3, "%d", &meta[2]);
return meta;
}
void img2list(FILE *fp,int x,int y,int bd,int *resultado,long tamano){
int dimx=x,dimy=y;
int bitDepth=bd;
long numeroPixeles=(dimx*dimy*bitDepth);
int con=0;
int pixels[numeroPixeles];
while (!feof(fp)){
pixels[con]=fgetc(fp);
con++;
}
memcpy(resultado,pixels,tamano);
}
void list2file(int *pixeles,int x,int y,int bitDepth, char nombre[]){
int dimx = x, dimy = y;
long numeroPixeles = dimx*dimy*bitDepth;
FILE *archivo = fopen(nombre, "wb"); /* b - binary mode */
(void) fprintf(archivo, "P6\n%d %d\n255\n", dimx, dimy);
for(long i=0;i<numeroPixeles;i++){
(void) fprintf(archivo,"%c",(char)pixeles[i]);
}
(void) fprintf(archivo,"\n");
(void) fclose(archivo);
}
int main(void){
int *meta;
int values,dimx,dimy;
int bitDepth=3;
FILE *fp = fopen("test.ppm","rb");
meta=getMeta(fp); // Dimenciones de la imagen
dimx = meta[0];
dimy = meta[1];
values = meta[2];
printf("dimencion en x: %d\n",dimx);
printf("dimencion en y: %d\n",dimy);
printf("cantidad de valores por pixel: %d\n",values);
long tamano=(dimx*dimy*bitDepth*sizeof(int));
int *pixeles=malloc(tamano);
img2list(fp,dimx,dimy,3,pixeles,tamano);
char nombre[]="pena.ppm";
list2file(pixeles,dimx,dimy,bitDepth,nombre);
(void) fclose(fp);
return EXIT_SUCCESS;
}
谢谢。
最佳答案
这个:
int pixels[numeroPixeles];
是堆栈溢出,除非numeroPixeles
受一个小常量限制。在堆栈上分配大对象无法区分成功/失败;您的程序刚刚崩溃(并且可能在编写您正在处理的数据的任何人的控制下产生代码执行)。要像这样处理任意大小的数据,您需要 malloc
,您可以在其中检查是否成功。
关于c - fgetc() 和 feof() 抛出大文件段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58333688/