Ir ao conteúdo
  • Cadastre-se

Programa em C: malloc() dentro de outra função


Pedrohtico

Posts recomendados

Olá, eu estou fazendo um programa que lê imagens PPM, mas estou tendo um problema. A seguinte função lê a imagem e guarda dentro de variáveis criadas na main. O problema está no ponteiro de ponteiro, ou seja, a matriz "pixel":

typedef struct{
    int r, g, b;
}matriz_pixel;

void ler_imagem(matriz_pixel **pixel, int *largura, int *altura, int *max, char *code, char *argv[]){  // Lê os primeiros valores do arquivo PPM

    int i, j;
    FILE *imagem;
    char nome[101];

    scanf("%s", nome);

    imagem = fopen(nome, "r");   // Abre o arquivo da imagem PPm
    if(imagem == NULL){
        printf("Erro na abertura do arquivo!\n");
        exit(1);
    }

    fscanf(imagem, "%s", code);
    fscanf(imagem, "%d", largura);
    fscanf(imagem, "%d", altura);
    fscanf(imagem, "%d", max);

    pixel = (matriz_pixel**) malloc (*altura * sizeof(matriz_pixel*));  // Aloca a matriz de struct que guardará os valores RGB
    if(pixel == NULL){
        printf("Erro de memoria!\n");
        exit(1);
    }
    for(i = 0; i < *altura; i++){
        pixel[i] = (matriz_pixel*) malloc (*largura * sizeof(matriz_pixel));
        if(pixel[i] == NULL){
            printf("Erro de memoria!\n");
            exit(1);
        }
    }

    printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b);

    for(i = 0; i < *altura; i++){
        for(j = 0; j < *largura; j++){
            fscanf(imagem, "%d", &pixel[i][j].r);
            fscanf(imagem, "%d", &pixel[i][j].g);
            fscanf(imagem, "%d", &pixel[i][j].b);
        }
    }

    printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b);

    fclose(imagem);
}

Essa segunda função eu fiz apenas para saber se os valores estavam sendo guardados corretamente:

 

void escrever_variaveis(matriz_pixel **pixel, int largura, int altura, int max, char *code){

    printf("Code: %s\n", code);
    printf("Largura: %d\n", largura);
    printf("Altura: %d\n", altura);
    printf("Tonalidade max: %d\n", max);
    printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0][0].r, pixel[0][0].g, pixel[0][0].b);

}

E então, tem a função main(), que apenas inicializa as variáveis e chama as duas funções anteriores:

 

int main(int argc, char *argv[]){

    int i, j;

    matriz_pixel **pixel;            // Variáveis dos atributos da imagem PPM
    int max, largura, altura;
    char code[3];

    ler_imagem(pixel, &largura, &altura, &max, code, argv);

    escrever_variaveis(pixel, largura, altura, max, code);

    free(pixel);
    for(i = 0; i < altura; i++){
        free(pixel[i]);
    }

    return 0;
}

Eu coloquei um printf para mostrar o valor RGB guardado dentro do primeiro pixel da matrix de struct "pixel". Esse printf foi colocado 3 vezes. A primeira vez ela printa o lixo logo depois de alocar a matriz pixel. Na segunda o valor após ler a imagem PPM. E a terceira, que fica na segunda função, deveria mostrar os mesmos valores que a segunda vez. Entretanto, o cmd dá mal funcionamento nesse printf e encerra o programa. Eu imagino que seja algum problema com a alocação dentro da função, como por exemplo se ela desalocasse quando acabasse a função, pois os valores são printados na segunda vez de forma correta. Apenas a terceira vez dá problema. Agradeço a ajuda desde já.

 

Edit 1: Ao retirar o terceiro printf, a variável (matriz_pixel **pixel) no nome da função e (pixel) na chamada dela, ela contina dando esse erro. Então eu descobri que tanto esse terceiro printf quanto o free(pixel) no final do main estão dando esse erro (se eu retirar essas duas partes, o programa funciona normalmente), o que me faz acreditar que é justamente algum problema com a alocação da matriz "pixel" dentro da função "ler_imagem".

 

Edit 2: Se eu inicializo a variável "matriz_pixel pixel**" globalmente, o programa para de dar erro e funciona normalmente.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Então vangodp, ajudou bastante e acho que entendi, mas não está dando certo na prática:

 

Eu mudei para um vetor, como você mostrou ser mais prático (e realmente vai ser, em outras funções que vou utilizar no programa) e, pela lógica, quando eu passasse para a função, a função deveria receber um **pixel, já que foi criado um *pixel. Ficou dessa forma:

 

void ler_imagem(matriz_pixel **pixel, int *largura, int *altura, int *max, char *code, char *argv[]){  // Lê os primeiros valores do arquivo PPM

    int i, j;
    FILE *imagem;
    char nome[101];

    scanf("%s", nome);

    imagem = fopen(nome, "r");   // Abre o arquivo da imagem PPM
    if(imagem == NULL){
        printf("Erro na abertura do arquivo!\n");
        exit(1);
    }

    fscanf(imagem, "%s", code);
    fscanf(imagem, "%d", largura);
    fscanf(imagem, "%d", altura);
    fscanf(imagem, "%d", max);

    *pixel = (matriz_pixel*) malloc((*largura)*(*altura)*sizeof(matriz_pixel));
    if(*pixel == NULL){
        printf("Erro de memoria!\n");
        exit(1);
    }

    printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0]->r, pixel[0]->g, pixel[0]->b);

    for(i = 0; i < *altura; i++){
        for(j = 0; j < *largura; j++){
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->r);
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->g);
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->b);
            printf("PIXEL 1: R: %d G: %d B: %d  (%d) (%d)\n", pixel[(*altura)*i + j]->r, pixel[(*altura)*i + j]->g, pixel[(*altura)*i + j]->b, i, j);
        }
    }

    printf("PIXEL 1: R: %d G: %d B: %d\n", pixel[0]->r, pixel[0]->g, pixel[0]->b);

    fclose(imagem);
}

int main(int argc, char *argv[]){

    int i, j; // Variáveis auxiliares

    matriz_pixel *pixel;
    int max, largura, altura; // Variáveis dos atributos da imagem PPM
    char code[3];

    ler_imagem(&pixel, &largura, &altura, &max, code, argv);

    escrever_variaveis(&pixel, largura, altura, max, code);

    free(pixel);

    return 0;
}

 

O que acontece agora é que ele não está lendo os valores do arquivo e guardando nas variáveis. Na verdade, quando executa, ele lê os três primeiros valores, ou seja, o primeiro pixel, sendo os valores R, G, B, e guarda na primeira posição do vetor, que contém a struct matriz_pixel. E logo depois ele para de funcionar. Então eu creio que é algum problema com a alocação talvez, já que ele guarda os valores apenas na posição 0 do vetor e não nas outras.

 

P.S.: Quando você falou que para manipular o vetor, teria que ser [i*j], acredito eu que teria que ser [10*i + j]. Pois apenas multiplicando o valor de i*j, você teria um problema na linha e na coluna 0, onde todos os valores dariam na posição 0 do vetor.

 

Edit 1: Eu testei guardando apenas na posição 0 do vetor e realmente está funcionando desse jeito, ou seja, os valores não estão sendo guardados apenas dentro da função, mas posso usá-los em outras funções também. O problema é que ele está alocando apenas a posição 0 do vetor e não as demais.

Link para o comentário
Compartilhar em outros sites

Deu certo.

 

Na verdade eu só mudei essa parte:

 

for(i = 0; i < *altura; i++){
        for(j = 0; j < *largura; j++){
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->r);
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->g);
            fscanf(imagem, "%d", &pixel[(*altura)*i + j]->b);
            printf("PIXEL 1: R: %d G: %d B: %d  (%d) (%d)\n", pixel[(*altura)*i + j]->r, pixel[(*altura)*i + j]->g, pixel[(*altura)*i + j]->b, i, j);
        }
    }

para isso:

 

for(i = 0; i < *altura; i++){
        for(j = 0; j < *largura; j++){
            fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].r);
            fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].g);
            fscanf(imagem, "%d", &(*pixel)[(*altura)*i + j].b);
            printf("PIXEL 1: R: %d G: %d B: %d  (%d) (%d)\n", (*pixel)[(*altura)*i + j].r, (*pixel)[(*altura)*i + j].g, (*pixel)[(*altura)*i + j].b, i, j);
        }
}

E o printf eu mudei do mesmo jeito:

 

De:

pixel[(*altura)*i + j]->r

Para:

(*pixel)[(*altura)*i + j].r

E deu certo dessa forma. Antes eu usei o debug e estava dando "Segmentation Fault". Mas pra mim essas 2 formas são equivalentes, não sei o porque da primeira dar erro e a segunda não. 

De qualquer forma, muito obrigado pela ajuda. :)

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!