Ir ao conteúdo
  • Cadastre-se
Gabriel Leal Silva

Erro sutil de segfault em um trabalho em c

Recommended Posts

Galera, estou a semana inteira estudando e fazendo esse trabalho pra faculdade. Agora, perto do prazo final(sexta 19h) ele está dando um erro muito sutil que eu não consigo perceber!!  No CodeBlocks, quando chega nas funções para achar jogadores na parte em que eu igual *jogador = &times.jogadores[j] o compilador simplesmente para de funcionar, no site da minha faculdade, diz que dá segmentation fault(não tenho Linux ainda, não testei lá)... O trabalho era só para implementar funções, então a main, eu que fiz mas no site da faculdade ele vai gerar uma main própria...Anexarei e também deixarei abaixo as duas versões do código, o lab4.h e o definições.h, incluídas no código e que tem instruções nos comentários. Me ajudem por favor, estou desesperado! P.S: o código é grande, mas as funções começam a quase que se repetir, mudando uma coisa ou outra, então, se achar meu erro no início é só mudar nas outra...

 

 

SEGUE ABAIXO AS INTRUÇÕES, LOGO APÓS O LAB4.H, DEFINICOES.H, E MEU CODIGO. ESTÁ MUITO GRANDE, ENTÃO SE PREFERIREM LEIAM SÓ AS INSTRUÇÕES E DEPOIS BAIXEM OS AQUIVOS QUE VOU DEIXAR ANEXADO. O CÓDIGO ESTÁ MUITO GRANDE, ENTÃO PRA FACILITAR, O ERRO ESTÁ MUITO PROVAVELMENTE NA TERCEIRA FUNÇÃO OU NAS DUAS ANTERIORES.

 

AQUI VOCÊS PODEM BAIXAR UM ARQUIVO PARA TESTAR O CÓDIGO: https://goo.gl/RLkcfx

P.S: Nome dos times e jogadores bugados pois foram gerados aleatoriamente.

 

***EDUT: TIREI AS INSTRUÇÕES AQUI.

 

 

Muito obrigado pela ajuda!! Lá vai:

 

 

 

#include <stdlib.h>
#include "lab4.h"

 


FILE *abre_arquivo(const char *arquivo){
    FILE *arq;
    arq = fopen(arquivo,"rb");
    if (arq == NULL){
        printf("ERRO");
        return NULL;
}
    return arq;
}

 

int fecha_arquivo(FILE *arq){
return fclose(arq);
}

 

times_t *le_times(const char *arquivo, unsigned int *numero_de_times){
    unsigned int i = 0;
    FILE *arqu = abre_arquivo(arquivo);
    times_t equipe;
        while(!feof(arqu)){
            i++;
            fseek(arqu,i*sizeof(times_t),SEEK_SET);
            fread(&equipe, sizeof(times_t),1,arqu);
   }
    *numero_de_times = i;
    times_t *times = (times_t*)malloc(i*sizeof(times_t));
    if(times == NULL){
       free(times);
       fecha_arquivo(arqu);
       return NULL;
       }
    fseek(arqu,0,SEEK_SET);
 int checagem = fread(times,sizeof(times_t),i,arqu);
 if (checagem < i){
                free(times);
                fecha_arquivo(arqu);
                return NULL;
            }
 fecha_arquivo(arqu);
   return times;
}

 

void encontra_jogador_cartao_vermelho_e_jogos(times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time){
    int i,j;
    float proporcao = 0.0;
    for (i = 0; i < num_times; i++){
        for(j = 0; j < NUM_JOGADORES; j++){
                if (((float)(times.jogadores[j].cartoes_vermelhos)/(times.jogadores[j].numero_jogos)) > proporcao){
                    proporcao = ((float)(times.jogadores[j].cartoes_vermelhos))/(times.jogadores[j].numero_jogos);
                    *jogador = &times.jogadores[j];
                    *time = &times;
               }
        }
    }
}

 

void encontra_jogador_artilheiro(times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time){
    int i,j,gols = 0;
    for (i = 0; i < num_times; i++){
        for(j = 0; j < NUM_JOGADORES; j++){
            if ((times.jogadores[j].gols_marcados) > gols){
                            gols = times.jogadores[j].gols_marcados;
                            *jogador = &times.jogadores[j];
                            *time = &times;
                    }
            }
        }
}

 

void encontra_jogador_mais_eficiente(times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time){
    int i,j;
    float artilharia = 0.0;
    for (i = 0; i < num_times; i++){
        for(j = 0; j < NUM_JOGADORES; j++){
            if (((float)(times.jogadores[j].gols_marcados))/(times.jogadores[j].numero_jogos) > artilharia){
                artilharia = ((float)(times.jogadores[j].gols_marcados))/(times.jogadores[j].numero_jogos);
                *jogador = &times.jogadores[j];
                *time = &times;
                    }
            }
        }
}

 

void encontra_time_com_mais_titulos(times_t *times, unsigned int num_times, times_t **time){
    int i;
    float titulo = 0.0;
        for(i = 0; i < num_times;i++){
           if (((float)(times.numero_copas_brasil + times.numero_tit_brasileiros + times.numero_tit_estadual + times.numero_tit_libertadores)/(times.ano_fundacao)) > titulo){
                titulo = (((float)(times.numero_copas_brasil + times.numero_tit_brasileiros + times.numero_tit_estadual + times.numero_tit_libertadores))/(times.ano_fundacao));
                *time = &times;
           }
        }
}

 

void encontra_goleiro_que_defendeu_mais_penaltis(times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time){
 int i,j;
 float defesas = 0.0;
 for (i = 0; i < num_times; i++){
        for(j = 0; j < NUM_JOGADORES; j++){
            if (times.jogadores[j].posicao == 0){
                if(((float)(times.jogadores[j].penalti_defendidos)/(times.jogadores[j].numero_jogos)) > defesas){
                    defesas = ((times.jogadores[j].penalti_defendidos)/(times.jogadores[j].numero_jogos));
                    *jogador = &times.jogadores[j];
                    *time = &times;
                        }
                    }
 }
 }
 }

 

void encontra_jogador_mais_agressivo(times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time){
int i,j;
float agressividade = 0.0, x;
     for (i = 0; i < num_times; i++){
            for(j = 0; j < NUM_JOGADORES; j++){
                x = 5*(times.jogadores[j].cartoes_vermelhos) + times.jogadores[j].cartoes_amarelos + 0.2*(times.jogadores[j].faltas_cometidas);
                if(x > agressividade){
                    agressividade = x;
                    *time = &times;
                    *jogador = &times.jogadores[j];
                }
}
     }

 

}

 


int main(void){

 

    int numeroDeTimes;
    char nomeArquivo[15] = "arq.dat";

 

    times_t *times = le_times(nomeArquivo, &numeroDeTimes);
    times_t *maiorTime;
    jogador_t *maiorJogador;
    encontra_jogador_cartao_vermelho_e_jogos(times,numeroDeTimes,&maiorJogador, &maiorTime);
    printf("%s \n",maiorTime->nome);
    printf("%s",maiorJogador->nome);
    encontra_jogador_artilheiro(times,numeroDeTimes,&maiorJogador, &maiorTime);
    encontra_jogador_mais_eficiente(times,numeroDeTimes,&maiorJogador, &maiorTime);
    encontra_time_com_mais_titulos(times,numeroDeTimes, &maiorTime);
    encontra_goleiro_que_defendeu_mais_penaltis(times,numeroDeTimes,&maiorJogador, &maiorTime);
    encontra_jogador_mais_agressivo(times,numeroDeTimes,&maiorJogador, &maiorTime);

 


    return 0;
}

 

 

 

definicoes.txt

lab4h.txt

 

 

lab4c.txt

Editado por Gabriel Leal Silva

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema está nessa linha de aqui:

numero_de_times = &i;

 

você esta atribuindo a direção de i a numero_de_times, porém mais abaixo na linha:

for ( i = 0; i < *numero_de_times; i++ ) ...

...você está alterando o valor de i, ou seja que numero_de_times está apontando uma variável que muda de valor constantemente. Essa variavel(numero_de_times) foi criada para manipular num da sua função main, ou seja, ela aponta a num dentro de main, você não pode atribuir outra variavel a esse ponteiro ou você perderá a direção de num e com isso a possibilidade de alteralo, troque a linha numero_de_times = &i; por *numero_de_times = i;, com issoo valor de i será atribuido a num dentro de main, posteriormente você poderá utilizar num para outros usos como por exemplo imprimir toda a lista de times.

 

Veja um exemplo:
 

#include <stdlib.h>
#include "lab4.h"


FILE *abre_arquivo ( const char *arquivo ) {
    FILE *arq;
    arq = fopen ( arquivo, "rb" );
    
    if ( arq == NULL ) {
        perror ( "ERRO" );
    }
    
    return arq;
}

times_t *le_times ( const char *arquivo, unsigned int *numero_de_times ) {
    unsigned int i = 0;
    FILE *arq;
    times_t equipe;
    arq = abre_arquivo ( arquivo );
    
    while ( !feof ( arq ) ) {
        i++;
        fseek ( arq, i * sizeof ( times_t ), SEEK_SET );
        fread ( &equipe, sizeof ( times_t ), 1, arq );
    }
    
    printf("Numero de times %d", i );
    
    *numero_de_times = i;
    times_t *times;
    times = ( times_t* ) malloc ( i * sizeof ( times_t ) );
    
    for ( i = 0; i < *numero_de_times; i++ ) {
        fseek ( arq, i * sizeof ( times_t ), SEEK_SET );
        fread ( &times[i], sizeof ( times_t ), 1, arq );
    }
    
    fclose ( arq );
    return times;
}

void encontra_jogador_cartao_vermelho_e_jogos ( times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time ) {
    int i, j;
    float proporcao = 0.0;
    
    for ( i = 0; i < num_times; i++ ) {
        for ( j = 0; j < NUM_JOGADORES; j++ ) {
            if ( ( float ) ( times[i].jogadores[j].cartoes_vermelhos ) / ( times[i].jogadores[j].numero_jogos ) > proporcao ) {
                proporcao = ( float ) ( times[i].jogadores[j].cartoes_vermelhos ) / ( times[i].jogadores[j].numero_jogos );
                *jogador = &times[i].jogadores[j];
                *time = &times[i];
            }
        }
    }
}

void encontra_jogador_artilheiro ( times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time ) {
    int i, j, gols = 0;
    
    for ( i = 0; i < num_times; i++ ) {
        for ( j = 0; j < NUM_JOGADORES; j++ ) {
            if ( ( times[i].jogadores[j].gols_marcados ) > gols ) {
                gols = times[i].jogadores[j].gols_marcados;
                *jogador = &times[i].jogadores[j];
                *time = &times[i];
            }
        }
    }
}

void encontra_jogador_mais_eficiente ( times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time ) {
    int i, j;
    float artilharia = 0.0;
    
    for ( i = 0; i < num_times; i++ ) {
        for ( j = 0; j < NUM_JOGADORES; j++ ) {
            if ( ( float ) ( times[i].jogadores[j].gols_marcados ) / ( times[i].jogadores[j].numero_jogos ) > artilharia ) {
                artilharia = ( float ) ( times[i].jogadores[j].gols_marcados ) / ( times[i].jogadores[j].numero_jogos );
                *jogador = &times[i].jogadores[j];
                *time = &times[i];
            }
        }
    }
}

void encontra_time_com_mais_titulos ( times_t *times, unsigned int num_times, times_t **time ) {
    int i;
    float titulo = 0.0;
    
    for ( i = 0; i < num_times; i++ ) {
        if ( ( ( float ) ( times[i].numero_copas_brasil + times[i].numero_tit_brasileiros + times[i].numero_tit_estadual + times[i].numero_tit_libertadores ) / ( times[i].ano_fundacao ) ) > titulo ) {
            titulo = ( ( float ) ( times[i].numero_copas_brasil + times[i].numero_tit_brasileiros + times[i].numero_tit_estadual + times[i].numero_tit_libertadores ) / ( times[i].ano_fundacao ) );
            *time = &times[i];
        }
    }
}

void encontra_goleiro_que_defendeu_mais_penaltis ( times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time ) {
    int i, j;
    float defesas = 0.0;
    
    for ( i = 0; i < num_times; i++ ) {
        for ( j = 0; j < NUM_JOGADORES; j++ ) {
            if ( times[i].jogadores[j].posicao == 0 ) {
                if ( ( ( float ) ( times[i].jogadores[j].penalti_defendidos ) / ( times[i].jogadores[j].numero_jogos ) ) > defesas ) {
                    defesas = ( ( float ) ( times[i].jogadores[j].penalti_defendidos ) / ( times[i].jogadores[j].numero_jogos ) );
                    *jogador = &times[i].jogadores[j];
                    *time = &times[i];
                }
            }
        }
    }
}

void encontra_jogador_mais_agressivo ( times_t *times, unsigned int num_times, jogador_t **jogador, times_t **time ) {
    int i, j;
    float agressividade = 0.0, x;
    
    for ( i = 0; i < num_times; i++ ) {
        for ( j = 0; j < NUM_JOGADORES; j++ ) {
            x = 5 * ( times[i].jogadores[j].cartoes_vermelhos ) + times[i].jogadores[j].cartoes_amarelos + 0.2 * ( times[i].jogadores[j].faltas_cometidas );
            
            if ( x > agressividade ) {
                agressividade = x;
                *time = &times[i];
                *jogador = &times[i].jogadores[j];
            }
        }
    }
    
    free ( times );
}

int fecha_arquivo ( FILE *arq ) {
    return fclose ( arq );
}


int main() {
    char nome[50] = "arq.dat";
    unsigned int num, i;
    times_t *time;
    jogador_t **jogador;
    times_t **equipe;
    FILE *arq;
    //scanf ( "%s", nome );
    arq = abre_arquivo ( nome );
    time = le_times ( nome, &num );  // time é um array de num(10... Depende do numero de times no arquivo) times. Num guarda o numero de times
    
	//imprime a lista de times para ver se o que retornou le_times é o array de times.
    for ( i = 0; i < num; i++ ) {
        printf ( "Time %d: %s\n", i+1, time[i].nome );
    }    
    
//    encontra_jogador_cartao_vermelho_e_jogos ( time, num, jogador, equipe );
//    encontra_jogador_artilheiro ( time, num, jogador, equipe );
//    encontra_jogador_mais_eficiente ( time, num, jogador, equipe );
//    encontra_time_com_mais_titulos ( time, num, equipe );
//    encontra_goleiro_que_defendeu_mais_penaltis ( time, num, jogador, equipe );
//    encontra_jogador_mais_agressivo ( time, num, jogador, equipe );

    free(time); // como time foi retornado pela função le_times e foi usado malloc para sua alocação precisa ser liberado com free.
    fecha_arquivo ( arq );
    return 0;
}

nesse exemplo você pode averiguar como obtemos corretamente a lista de times do arquivo desde le_times e a imprimimos dentro de main, o que significa que le_times funciona corretamente, ou mais ou menos heheh. Agora é só trabalhar as outras funções.

Editado por vangodp

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp cara, muito obrigado pela ajuda!! Mas infelizmente eu arrumei esse erro e mesmo assim continua acusando segfault lá no site! No CodeBlocks tá rodando tranquilo! Tô usando só uma versão do código agora que eu vou atualizar na postagem. To mandando também a main que eu to usando e tá dando certo. Continuo achando erro está em lê times ou na comparação do ponteiro duplo *jogador = &timesjogadores[j]. Muito obrigado pela ajuda!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp Haha é o mesmo trabalho! Ele é um amigo meu, foi ele quem me indicou o fórum! O problema dele ontem era com abrir o arquivo né? Darei uma olhada!! De qualquer forma, atualizei o código na postagem! Consegui tirar aquele for.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp hum, entendo. Cara, eu tentei com a função que você fez pra ele e deu a mesma coisa. Deu certo no pc mas lá no site não deu... Então não deve ser a le_times, deve ser no ponteiro duplo.. O erro que aparece no compilador do site:

 

Copiando arquivos de teste...                                                   

FIM                                                                             

./vpl_execution: line 16: 29242 Segmentation fault      (core dumped) ./$PROG   

 

 

e nos comentários de avaliação:

 

Copiando arquivos de teste...
FIM
Iniciando avaliação de compilação.
Acabou a avaliação de compilação.
Iniciando avaliação de tempo máximo de execução.
[☠☠☠] Erro: falha de segmentação (crashed)!
 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×