1
resposta

free() nao funciona

Ao chamar a funcao liberamapa() o programa trava e fecha, nao consigo descobrir o por que.

github do projeto: https://github.com/Marcelorpc/alurapacman

#include <stdio.h>
#include <stdlib.h>
#include "mapa.c"
#include "xxx.h"

MAPA m;
POSICAO heroi;
MAPA mcopy;

void fantasmas() {
    copiamapa(&m, &mcopy);
    for(int i = 0; i < m.linhas; i++) {
        for(int j = 0; j < m.colunas; j++) {
            if(mcopy.matriz[i][j] == FANTASMA) {
                if(direcaovalida(i, j+1)) {
                    andanomapa(i, j, i, j+1);
                }
            }
        }
    }
    liberamapa(&mcopy);
}

int entradavalida(char direcao) {
    if(direcao == ESQUERDA || direcao == DIREITA || direcao == CIMA || direcao == BAIXO) {
        return 1;
    } else {
        return 0;
    }
}

int direcaovalida(int x, int y) {
    if(m.matriz[x][y] == PAREDEHORIZONTAL) {
        return 0;
    } else if(m.matriz[x][y] == PAREDEVERTICAL) {
        return 0;
    } else {
        return 1;
    }
}

void andanomapa(int origemx, int origemy, int destinox, int destinoy) {
    char personagem = m.matriz[origemx][origemy];

    m.matriz[origemx][origemy] = VAZIO;
    m.matriz[destinox][destinoy] = personagem;
}

void move(char direcao) {
    int proximox = heroi.x;
    int proximoy = heroi.y;

    if(!entradavalida(direcao)) {
        return;
    }
    switch(direcao) {
        case ESQUERDA:
            proximoy--;
            break;
        case DIREITA:
            proximoy++;
            break;
        case CIMA:
            proximox--;
            break;
        case BAIXO:
            proximox++;
            break;
    }
    if(!direcaovalida(proximox, proximoy)){
        return;
    }
    andanomapa(heroi.x, heroi.y, proximox, proximoy);
    heroi.x = proximox;
    heroi.y = proximoy;    
}

int main() {
    lemapa(&m);
    encontraheroi(&m, &heroi, HEROI);
    do {
        imprimemapa(&m);
        char comando;
        scanf(" %c", &comando);
        move(comando);
        fantasmas();
    } while(0 == 0);
    liberamapa(&m);
    liberamapa(&mcopy);
} 
void liberamapa(MAPA* m) {
    for(int i = 0; i < m->linhas; i++) {
        free(m->matriz[i]);
    }
    free(m->matriz);
}

Ao chamar a funcao liberamapa() o programa trava e fecha, nao consigo descobrir o por que.

1 resposta

Considerando que vc só usa mcopy dentro de fantasmas(), e vc aloca e libera dentro desta função, quando vc chama liberamapa(&mcopy) dentro do main(), vc está chamamdo free() em uma variável que já foi liberada anteriormente.

Alguns pontos a considerar aqui:

  1. Vc pode corrigir isto removendo a chamada liberamapa(&mcopy) do main.
  2. Outra maneira poderia ser, em liberamapa, vc definir como NULL os valores após liberá-los, e testar se estes são válidos (diferentes de NULL) antes de usá-los.
  3. Em fantasmas(), vc cria uma cópia, mas não a altera em momento nenhum, assim vc poderia trabalhar diretamente com o mapa principal e evitar a necessidade de alocar e liberar esta cópia.