Program compiles but stops responding during execution

Asked

Viewed 186 times

2

I wrote a program that compiles, but is stopping responding during execution.

This program opens a PGM file and saves the derivative by convolution in saida.pgm.
The function LerPGM() receives a string with the filename and returns a dynamically allocated 2D array in img.

The function Convolucao() performs the convolution operation in the array img using a kernel already declared and saved in another array.
SalvarPGM() receives this other array and a string and then writes the array to a PGM file whose name is the received string.

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int c;
    int l;
    unsigned char maximo;
    unsigned char **imagem;
} PGM;

PGM *LerPGM(char* entrada);
void SalvarPGM(PGM *img, char* saida);
void Convolucao(PGM *img, char **kernel, PGM *saida);

int main()
{
    PGM *imgconv;
    char kernel[3][3]={{-1, 0, 1},{-1, 0, 1},{-1, 0, 1}};
    if(SalvarPGM(Convolucao(LerPGM("entrada.pgm"), kernel, imgconv), "saida.pgm")) printf("Operacao realizada com sucesso.");
    return 0;
}

PGM *LerPGM(char* entrada){
    PGM img;
    char tipo[3];
    int i, j;


    FILE *arq;
    arq = fopen(entrada, "r");
    if(arq == NULL){
        printf("Arquivo nao encontrado.");
        return 0;
    }

    fscanf(arq, "%s %d %d %d", &tipo, &img.c, &img.l, &img.maximo);
    if(strcmp(tipo, "P2")){
        printf("O arquivo nao e PGM.");
        return 0;
    }

    img.imagem = malloc(img.l * sizeof(char *));
    for(i=0; i<img.c; i++) img.imagem[i] = malloc(img.c * sizeof(char));
    if(img.imagem == NULL){
        printf("Falha na alocacao de memoria.");
        return 0;
    }

    for(i=0; i<img.l; i++){
        for(j=0; j<img.c; j++){
            fscanf(entrada, "%d", &img.imagem[i][j]);
        }
    }

    fclose(arq);

    return &img;
}

void Convolucao(PGM *img, char **kernel, PGM *saida){
    unsigned char aux[img->l+2][img->c+2];
    int i, j, k, l, soma;
    saida = img;

    for(i=1; i<img->l+1; i++){
        for(j=1; j<img->c+1; j++){
            aux[i][j] = img->imagem[i-1][j-1];
        }
    }

    for(i=1; i<img->l+1; i++){
        aux[i][0] = aux[i][1];
        aux[i][img->c+1] = aux[i][img->c];
    }
    for(j=0; j<img->c+2; j++){
        aux[0][j] = aux[1][j];
        aux[img->l+1][j] = aux[img->l][j];
    }

    for(i=1; i<img->l+1; i++){
        for(j=1; j<img->c+1; j++){
            soma=0;
            for(k=2; k>=0; k--){
                for(l=2; l>=0; l--){
                    soma+=kernel[k][l]*aux[i+(1-k)][j+(1-l)];
                }
            }
            if(soma<=0) saida->imagem[i-1][j-1]=0;
                else if(soma>=255) saida->imagem[i-1][j-1]=255;
                    else saida->imagem[i-1][j-1]=soma;
        }
    }

    free(img);
    free(aux);

    return saida;
}

void SalvarPGM(PGM *img, char* saida){
    int i, j;
    FILE *arq;

    arq = fopen("saida.pgm", "w");
    if(arq == NULL){
        printf("Ocorreu um erro.");
        return 0;
    }
    fprintf(arq, "%s\n%d %d %d", "P2", img->c, img->l, img->maximo);
    for(i=0; i<img->l; i++){
        fprintf(saida,"\n");
        for(j=0; j<img->c; j++){
            fprintf(saida, "%d ", img->imagem[i][j]);

        }
    }

    fclose(arq);
    free(img);
    return 1;
}

This program is stopping responding and I don’t know exactly why. I don’t know if I’m using the pointers wrong (or maybe the structs) or if I’m allocating them erroneously. When I don’t use functions the program works perfectly. For example:

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int c;
    int l;
    unsigned char maximo;
    unsigned char **imagem;
} PGM;

int main()
{
    PGM img;
    char tipo[10];
    int i, j, k, kk;
    FILE *entrada;
    entrada=fopen("entrada.pgm", "r");
    if(entrada==NULL){
        printf("Arquivo nao encontrado.");
        return 0;
    }
    fscanf(entrada, "%s %d %d %d", &tipo, &img.c, &img.l, &img.maximo);
    if(strcmp(tipo, "P2")){
        printf("O arquivo nao e PGM.");
        return 0;
    };

    img.imagem=malloc(img.l * sizeof(char *));
    for(i=0; i<img.c; i++) img.imagem[i]=malloc(img.c * sizeof(char));
    if(img.imagem==NULL) printf("Ocorreu um erro!");
    for(i=0; i<img.l; i++){
        for(j=0; j<img.c; j++){
            fscanf(entrada, "%d", &img.imagem[i][j]);
        };
    };

    int kernel[3][3]={{-1, 0, 1}, {-1, 0, 1},{-1, 0, 1}};
    unsigned char aux[img.l+2][img.c+2];
    for(i=1; i<img.l+1; i++){
        for(j=1; j<img.c+1; j++){
            aux[i][j]=img.imagem[i-1][j-1];
        };
    };


    for(i=1; i<img.l+1; i++){
        aux[i][0]=aux[i][1];
        aux[i][img.c+1]=aux[i][img.c];
    };
    for(j=0; j<img.c+2; j++){
        aux[0][j]=aux[1][j];
        aux[img.l+1][j]=aux[img.l][j];
    };

    int soma;
    for(i=1; i<img.l+1; i++){
        for(j=1; j<img.c+1; j++){
            soma=0;
            for(k=2; k>=0; k--){
                for(kk=2; kk>=0; kk--){
                    soma+=kernel[k][kk]*aux[i+(1-k)][j+(1-kk)];
                };
            };
            if(soma<=0) img.imagem[i-1][j-1]=0;
                else if(soma>=255) img.imagem[i-1][j-1]=255;
                    else img.imagem[i-1][j-1]=soma;
        };
    };

    fclose(entrada);
    FILE *saida;
    saida=fopen("saida.pgm", "w");
    fprintf(saida, "%s\n%d %d %d", tipo, img.c, img.l, img.maximo);
    for(i=0; i<img.l; i++){
        fprintf(saida,"\n");
        for(j=0; j<img.c; j++){
            fprintf(saida, "%d ", img.imagem[i][j]);

        };
    };

    fclose(saida);

    return 0;
}
  • The function return type SalvarPGM is void the if in main won’t work.

1 answer

2


int main()
{
    PGM *imgconv;
    char kernel[3][3]={{-1, 0, 1},{-1, 0, 1},{-1, 0, 1}};
    if(SalvarPGM(Convolucao(LerPGM("entrada.pgm"), kernel, imgconv), "saida.pgm")) printf("Operacao realizada com sucesso.");
    return 0;
}

The line that "does work" has a very strange thing:

    if(SalvarPGM(Convolucao(LerPGM("entrada.pgm"), kernel, imgconv), "saida.pgm")) printf("Operacao realizada com sucesso.");

The if no matter for the weirdness: to simplify remove it from the instruction

    SalvarPGM(Convolucao(LerPGM("entrada.pgm"), kernel, imgconv), "saida.pgm");

The function SalvarPGM() is defined as receiving 2 parameters: 1 of type PGM * and another type char *.

The first parameter is the result of the (sub-)expression Convolucao(LerPGM("entrada.pgm"), kernel, imgconv) whose type is void. Very odd!


My suggestion is to turn on as many warnings on your compiler and not accept an executable that has been produced with a "dirty build".

  • 2

    I agree. really the if is useless aiming that the method SalvarPGM returns void.

  • hehe .. I didn’t even notice the function SalvarPGM(): I started reading from "inside out".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.