c - fgetc() 和 feof() 抛出大文件段错误

标签 c runtime-error

我正在尝试编写一个程序来处理 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/

相关文章:

c - Stack Smashing 尝试给出段错误

c - 在C中将数字写到没有printf的文件中?

python - 我该如何解决这个错误?类型错误 : 'str' does not support the buffer interface

android - 如何防止 OneLogin Protect android app v4.3.0 崩溃?

c - C 中的实例级抽象

c - 从文本文件中读取并拆分 C 中的值

c - 将头节点添加到单链表会产生段错误

types - 如何在制作实例期间强制检查插槽的类型?

C# 运行时错误声明主体,因为它未标记为抽象、外部或部分

codenameone aap 中的运行时错误