Ir para conteúdo
Fórum Script Brasil
  • 0

Erro segmentation fault e free(): double free


fredericopaula

Pergunta

 

Olá estou a implementar um jogo de palavras cruzadas, em que o computador utiliza um dicionário para testar diferentes jogadas que pode fazer no tabuleiro. Diferentes palavras valem diferente pontuação. Na primeira jogada a palavra colocada tem de ter, pelo menos uma letra no tabuleiro, as seguintes terão de utilizar pelo menos uma letra já colocada no tabuleiro.

Estou a ter problemas nas jogadas seguintes à primeira. Supostamente, ao fim de cada jogada é registado numa lista simples e depois é libertada para ser usada na jogada seguinte,mas por alguma razão não é possível usa-la de novo. Qual será o problema?

 

 

 

void jogadas(char **tab, int tamanho, dicionario *headD[], FILE *reg)
{
    int i, j, k, pontof=0, ponto=0, max=0, erro=0, auxlin;
    char **tab_aux = NULL, auxcol;
    dicionario *read=NULL;
    pc *casaR = NULL;

    auxlin = (tamanho+1)/2;
    tab_aux = loadtabuleiro(tab, tamanho);

    for(counter=0; counter<2; counter++) //&& condiçao de paragem de jogo
    {
        //primeira jogada

        /*aqui são testadas todas as palavras do dicionário (percorrendo todos os elementos da lista) em cada coluna na casa inicial e filtradas pela
        função erros() que caso retorne 0 a palavra é aceite é registada nos registos da primeira jogada, com os seus respetivos pontos.

        é guardado o máximo de pontos, de entre todas as tentativas feitas pelo computador, para depois ser colocada no tabuleiro
        */

        //jogada 1
            if(counter==0)
            {
                for(i=tamanho-2; i>=0; i--)
                {
                    for( read=headD[i] ; read!=NULL; read = read->nextw)
                    {

                        for(k=1; k<=tamanho; k++)
                        {
                            auxcol = (char) (k+'A'-1);

                            if((erro = erros(tab, tamanho, k, auxlin, 'H', read->Word, counter)) == 0)
                            {
                                ponto = atribuirpontos(read->Word, tab_aux, k, auxlin, 'H', tamanho);
                                max = maxpoints(max, ponto);
                                NovaJogada = nova_jogada(auxcol, auxlin, 'H', read->Word, ponto); // printf
                                head = inserir_jogada_na_lista(NovaJogada, head);
                            }
                        }
                    }
                }
                pontof = max;
            }

        //restantes jogadas
            else
            {
                //guardar numa lista as casas que têm letras
                for(i=0 ; i<tamanho; i++)
                {
                    for(j=0; j<tamanho; j++)
                    {
                        if(tab[i][j]>='a' && tab[i][j]<='z')
                        {
                            NovaCasa = casa(i+1, j+1);
                            lhead = inserir_casa_na_lista(lhead, NovaCasa);
                        }
                    }
                }

                readlistpc(lhead);
                //tentativa vertical

                for( casaR = lhead; casaR!=NULL ; casaR = casaR->next)
                {
                    for(i=tamanho-2; i>=0; i--)
                    {

                        for( read=headD[i] ; read!=NULL; read = read->nextw)
                        {

                            for(k=1; k<=tamanho; k++)
                            {
                                auxcol = (char) (casaR->c+'A'-1);

                                if((erro = erros(tab, tamanho, casaR->c, k, 'V', read->Word, counter)) == 0)
                                {

                                    ponto = atribuirpontos(read->Word, tab, casaR->c, k, 'V', tamanho);
                                    printf("\n%d\n", ponto);
                                    fflush(stdout);
                                    max = maxpoints(max, ponto);
                                    NovaJogada = nova_jogada(auxcol, k, 'V', read->Word, ponto); // printf
                                    printf("%c%d%c %s %d pontos\n", NovaJogada->col, NovaJogada->lin, NovaJogada->lin, NovaJogada->palavra, NovaJogada->ponto);
                                    fflush(stdout);
                                    head = inserir_jogada_na_lista(NovaJogada, head);
                                }
                            }
                        }
                    }
                }
                pontof += max;
            }

            tab = procurar_jogada_max(head, max, tab);
            fprintf(reg,"Jogada %d\n", counter+1);
            for(i=max; i>=(max+1)/2; i--)
            {
                procurar_jogadas_reg(head, i, reg);
            }
            free_reg(head);
            free(NovaJogada->palavra);
            free(NovaJogada);
            head = NULL;
            max=0;
            erro=0;

    }

    for(i=0; i<tamanho; i++)
    {
        free(tab_aux[i]);
    }
    free(tab_aux);
}

// função que proibe tentativas inválidas, retornando 0 caso seja válida
int erros(char **tab, int tamanho, int auxcol, int lin, char dir, char *palavra, int counter)
{
    int i, aux;
    aux = (tamanho+1)/2;

    //restricão à direção
    if(dir!='H' && dir!='V' && dir!='h' && dir!='v')
        return (-1);

    //restrição para uso de apenas e so maiusculas
    if((lin>tamanho || lin<0) && (auxcol>tamanho || auxcol<0))
        return (-1);

    //erros na direção horizontal
    if(dir=='H' || dir=='h')
    {
        //casa proibida(primeira condição) e proibição da palavra exceder o tabuleiro(segunda condição)
        for(i=0; i<strlen(palavra); i++)
        {
            if(tab[lin-1][auxcol-1+i]=='#'|| strlen(palavra)+auxcol-1>tamanho)
                return (-1);
        }

        //primeira jogada com uma letra na casa central do tabuleiro
        if(counter==0)
        {
            if(lin!=aux)
                return (-1);
            else
            {
                if(auxcol>aux || aux>auxcol+strlen(palavra)-1)
                    return (-1);
            }
        }

        if(counter>0)
        {
            for(i=0; i< lin+strlen(palavra)-1; i++)
            {
                if(tab[lin-1][auxcol+i-1]>='a' && tab[lin-1][auxcol+i-1]<='z' && palavra[i] != tab[lin-1][auxcol+i-1])
                    return (-1);
                if(tab[lin-1][auxcol+i-1]<'a' || tab[lin-1][auxcol+i-1]>'z')
                    return (-1);
            }
        }
    }

    //erros na direção vertical
    if(dir=='V' || dir=='v')
    {
        //casa proibida(primeira condição) e proibição da palavra exceder o tabuleiro(segunda condição)
        for(i=0; i<(strlen(palavra)); i++)
        {
            if(tab[lin-1+i][auxcol-1]=='#' || strlen(palavra)+lin-1>tamanho)
                return (-1);
        }

        //proibição da primeira jogada na vertical
        if(counter==0)
            return (-1);

        if(counter>0)
        {
            for(i=0; i< auxcol + strlen(palavra)-1; i++)
            {
                if(tab[lin+i-1][auxcol-1]>='a' && tab[lin+i-1][auxcol-1]<='z' && palavra[i] != tab[lin+i-1][auxcol-1])
                    return (-1);
                if(tab[lin+i-1][auxcol-1]<'a' || tab[lin+i-1][auxcol-1]>'z')
                    return (-1);
            }
        }
    }

 

jogada *nova_jogada(char col, int lin, char dir, char *palavra, int ponto)
{
    jogada *NewJ=NULL;

    if(( NewJ = (jogada*) malloc(sizeof(jogada))) == NULL)
    {
        system("cls");
        printf("\nERRO DE ALOCAÇÃO\n");
        exit(EXIT_FAILURE);
    }

    if((NewJ->palavra = (char *) malloc((strlen(palavra)+1)*sizeof(char))) == NULL)
    {
        system("cls");
        printf("\nERRO DE ALOCAÇÃO\n");
        exit(EXIT_FAILURE);
    }

    NewJ->col = col;
    NewJ->lin = lin;
    NewJ->dir = dir;
    strcpy(NewJ->palavra, palavra);
    NewJ->ponto = ponto;
    NewJ->next = NULL;

    return NewJ;
}

//função que insere uma tentativa válida na lista de registos de jogadas
jogada *inserir_jogada_na_lista(jogada *NovaJogada, jogada *head)
{
    jogada *AuxT = NULL;


    if( head == NULL)
        head = NovaJogada;

    else
    {
        AuxT = head;

        while(AuxT->next != NULL)
            AuxT = AuxT->next;

        AuxT->next = NovaJogada;
    }

    return head;
}

//função procura a primeira tentaiva válida encontrada com pontuação máxima, coloca no tabuleiro e faz print do tabuleiro
char **procurar_jogada_max(jogada *head, int max, char **tab)
{
    jogada *searchM = NULL;
    int i;

    if(head == NULL)
    {
        return NULL;
    }

    else
    {
        searchM = head;

        while(searchM != NULL)
        {
            if(searchM->ponto == max)
                break;
            searchM = searchM->next;
        }
        //problema aqui

        if(searchM->dir == 'H')
        {
            for(i=0; i<strlen(searchM->palavra); i++)
            {
                tab[(searchM->lin)-1][(int)((searchM->col)- 'A')+i] = (searchM->palavra)[i];
            }
        }

        if(searchM->dir == 'V')
        {
            for(i=0; i<strlen(searchM->palavra); i++)
                tab[(searchM->lin)-1+i][(int)((searchM->col)- 'A')] = (searchM->palavra)[i];
        }

        printf("\n\n");
        print_tabuleiro(tab, tamanho);
        printf("\n%c%d%c %s %d pontos\n", searchM->col, searchM->lin, searchM->dir, searchM->palavra, searchM->ponto);
        fflush(stdout);
    }

    return tab;
}

//função procura todas as tentativas até uma (máximo+1)/2 da pontuação máximo e escreve-as na file de registo
void procurar_jogadas_reg(jogada *head, int i, FILE *reg)
{
    jogada *searchJ = NULL;

    for( searchJ = head; searchJ != NULL; searchJ = searchJ->next)
    {
        if(searchJ->ponto == i)
        {
            fprintf(reg, "%c%d%c %s %d PONTOS\n", searchJ->col, searchJ->lin, searchJ->dir, searchJ->palavra, searchJ->ponto);
        }
        //printf("%c%d%c %s %d PONTOS\n", searchJ->col, searchJ->lin, searchJ->dir, searchJ->palavra, searchJ->ponto);
    }
}

//função de free nos registos de cada jogada (free na memória alocada da palavra e da estrutura
void free_reg(jogada *head)
{
    jogada *del = NULL;

    while(head != NULL && head->next!=NULL)
    {
        del = head;
        head = head->next;
        free(del->palavra);
        free(del);
    }
}

Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...