Ir ao conteúdo
  • Cadastre-se

Falha de segmentação em funções não relacionadas


Matheus Perusso

Posts recomendados

Bem, estou fazendo um programa de uma locadora de carros, eu tenho a função de registrar clientes, aparentemente ela está funciondo normalmente, mas se dps q eu registrar alguns clientes, eu decidir registrar uma filial dessa empresa(e consigo), dps q eu registro essa filial, se eu tentar registrar um cliente, da falha de segmentação logo após eu escrever o primeiro nome. Não entendo o porque dessa falha, as duas funções não interagem, se eu tentar registrar um veiculo, funciona normalmente. Segue o código(É imenso, mas vou destacar somente as duas funções com problemas).

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
  int nc=0,ncar=-1,numeroc=0,nf=1,*pfiliais=&nf,*p=&nc,*pcar=&ncar;


  typedef struct{
   char pnome[100],unome[100];
   int cpf[12],numcadastro[100],senha[100];
   char endereco[100];
  }ficha;

  typedef struct{
    int filialloc[3];
    char placa[9],marca[30],modelo[30];
    int  ano[2],estado[2];
    float quilometragem[2];

  }cadastrocarro;

  typedef struct{
    char nomef[50];
    int identificadorcarros[50],numerodecarros[5];
  }filial;



  void cadastro(ficha cliente[nc]){
    __fpurge(stdin);                        //AQUI É AONDE COMEÇA A REGISTRAR O CLIENTE.
    printf("\n Digite seu primeiro nome: ");
    scanf("%s",cliente[nc].pnome);
    __fpurge(stdin);
    printf(" Digite seu sobrenome: ");
    fgets(cliente[nc].unome,100,stdin);
  }

  void vercpf(ficha cliente[nc]){
    int verificador=0;
    for(;verificador==0;){
      int vet[11],i,mult1=0,n1=10,dig1=0,mult2=0,n2=11,dig2=0,cont=0,contador=0,verificador2=0;;
      char cpf[12],stroca[2];
      verificador=0;
      __fpurge(stdin);
     printf("\n %s, digite seu cpf no formato(XXXXXXXXXXX) : ", cliente[nc].pnome);
     fgets(cpf,12,stdin);
     for(i=0;i<11;i++){
       stroca[0]=cpf[i];
       vet[i]=atoi(stroca);
     }
     for(i=1;i<11;i++){
       if(vet[0]==vet[i]){
         cont++;
       }
     }
     for(i=0;i<10;i++){
       if(i<9){
        mult1+=vet[i]*n1;
          n1--;
       }
       mult2+=vet[i]*n2;
       n2--;
    }


      if(mult1%11<2){
        dig1=0;
      }else{
        dig1=11-(mult1%11);
      }
      if(mult2%11<2){
        dig2=0;
      }else{
        dig2=11-(mult2%11);
      }
      verificador2=0;
      for(int k=0;k<nc;k++){
        contador=0;
        for(int m=0;m<11;m++){
          if(cliente[k].cpf[m]==vet[m]){
          contador++;
          if(contador==11){
            verificador2++;
            printf("\n CPF já existe no sistema\n");
          }
        }
        }
      }

    if((dig1!=vet[9] && dig2!=vet[10])||(dig1==vet[9] && dig2!=vet[10])|| (dig1!=vet[9] && dig2==vet[10])|| cont==10||strlen(cpf)<10){
      printf(" CPF inválido");
      __fpurge(stdin);
      cont=0;
    }else{
      if(verificador2==0){
      for(i=0;i<11;i++){
        cliente[nc].cpf[i]=vet[i];
      verificador++;
      }
      }
    }
    }
  }
  void numcadast(ficha cliente[nc]){
    int verificador=1,contador=0,verificador2=0;
    for(;verificador>0;){
    int vetcadast[5],i,mult=0,n=9,dig=0,var=0,caracteres=0;
    char cadast[6],stroca[2];
    __fpurge(stdin);
     printf("\n %s, digite o numero base para seu identificador(4 primeiros números): ", cliente[nc].pnome);
     scanf("%s", cadast);
     if(strlen(cadast)!=4){
       verificador++;
         printf("\n Verificador inválido- Número base deve ter somente 4 digitos\n");
     }else{
       verificador=0;
       for(i=0;i<5;i++){
         stroca[0]=cadast[i];
         vetcadast[i]=atoi(stroca);
       }
       for(i=0;i<4;i++){
         mult+=vetcadast[i]*n;
         n--;
       }
        var=mult%11;
        if(var==10){
          vetcadast[4]=0;
        }else{
          vetcadast[4]=var;
        }
        for(int k=0;k<nc;k++){
          contador=0;
          for(int m=0;m<4;m++){
            if(cliente[k].numcadastro[m]==vetcadast[m]){
            contador++;
            if(contador==4){
              verificador++;
              printf(" Identificador já existe no sistema\n");
            }
          }
          }
        }
        if(verificador==0){
          for(i=0;i<5;i++){
            cliente[nc].numcadastro[i]=vetcadast[i];
          }
        }
        }
      }
    }
        void senhac(ficha cliente[nc]){
          char senh[7],stroca1[2];
          int vetsenha[6],verificador=0;
          for(;verificador==0;){
          printf("\n %s, Digite sua senha(6 números): ", cliente[nc].pnome);
          scanf("%s", senh);

          if(strlen(senh)!=6){
            printf(" A senha precisa ter 6 números");
            verificador=0;
          }else{
          for(int k=0;k<6;k++){
            stroca1[0]=senh[k];
            vetsenha[k]=atoi(stroca1);
          }
          for(int i=0;i<6;i++){
          cliente[nc].senha[i]=vetsenha[i];
          verificador++;
            }
          }
        }
      }
    void enderecoc(ficha cliente[nc]){
      __fpurge(stdin);
      printf("\n %s, digite seu endereço: ", cliente[nc].pnome);
      fgets(cliente[nc].endereco,100,stdin);
    }

    void placacarro(cadastrocarro carro[ncar]){
      int verificador=0;
      for(;verificador==0;){
      char placa[9];
      int cont=0;
      __fpurge(stdin);
      printf("\n Digite a placa do carro(XXX0000): ");
      fgets(placa,9,stdin);
      for(int i=0;i<ncar;i++){
        if(strcmp(carro[i].placa, placa) == 0){
              cont++;
        }
      }
      if(strlen(placa)!=8|| cont>0){
        verificador=0;
        printf(" Placa inválida ou já consta no sistema\n");
        __fpurge(stdin);
      }else{
        verificador++;
        strcpy(carro[ncar].placa, placa);
      }
     }
   }



   void restofichacarro(cadastrocarro carro[ncar]){
     __fpurge(stdin);
     printf("\n Digite a marca do carro: ");
     fgets(carro[ncar].marca,30,stdin);
     __fpurge(stdin);
     printf("\n Digite o modelo do carro: ");
     fgets(carro[ncar].modelo,30,stdin);
     __fpurge(stdin);
     printf("\n Digite o ano do carro: ");
     scanf("%d", carro[ncar].ano  );
     printf("\n Digite um número que representa o estado do carro(Sendo 10 muito bom e 0 horrivel): ");
     scanf("%d", carro[ncar].estado);
     printf("\n Digite a quilometragem do carro(KM): ");
     scanf("%f", carro[ncar].quilometragem);
     }

     void filiaisc(cadastrocarro carro[ncar], filial carrosdafilial[nf]){ //AQUI EU REGISTRO AS FILIAIS
       int verificador=0;
       for(;verificador==0;){
          int identificador;
         printf(" Digite o identificador da filial em que deseja cadastrar o carro(Sede Chapecó=0): ");
         scanf("%d", &identificador);
         if(identificador<nf && identificador>0 || identificador==0){

           carrosdafilial[identificador].identificadorcarros[carrosdafilial[identificador].numerodecarros[0]]=ncar;
           carrosdafilial[identificador].numerodecarros[0]+=1;
           carro[ncar].filialloc[0]=0;
           carro[ncar].filialloc[1]=identificador;
           verificador++;
         }else{
           printf("\n Identificador de sede inválido\n");
         }
       }

      }



     void criarfiliais(filial carrosdafilial[nf]){
       __fpurge(stdin);
       carrosdafilial[nf].numerodecarros[0]=0;
       printf("\n Digite a localização da filial: ");
       fgets(carrosdafilial[nf].nomef,50,stdin);
       printf("\n\nFilial %s cadastrada com sucesso. O Número de identificação da filial é: %d\n", carrosdafilial[nf].nomef, nf );

     }


      int main(){
        int escolha;
        ficha cliente[nc];
        cadastrocarro carro[ncar];
        filial carrosdafilial[nf];


        carrosdafilial[0].nomef[0]='C';carrosdafilial[0].nomef[1]='h';carrosdafilial[0].nomef[2]='a';carrosdafilial[0].nomef[3]='p';carrosdafilial[0].nomef[4]='e';
        carrosdafilial[0].nomef[5]='c';carrosdafilial[0].nomef[6]='o';


          do {
          escolha=90;
          __fpurge(stdin);
          printf("\n       MENU LOCADORA DE VEÍCULOS     \n\n");
          printf("  (1) Cadastro de novos clientes\n");
          printf("  (2) Cadastro de novos veículos\n");
          printf("  (3) Locação de carros\n");
          printf("  (4) Cadastro de novas filiais\n");
          printf("  (5) Movimentar carros\n");
          printf("  (6) Sair do programa\n");
          printf("\n Digite o número correspondente a sua ação :  ");
          scanf("%d", &escolha);




          switch (escolha){
            case 1:
                    cadastro(cliente);
                    vercpf(cliente);
                    numcadast(cliente);
                    senhac(cliente);
                    enderecoc(cliente);
                    *p+=1;
                    break;
            case 2:
                    *pcar+=1;
                    filiaisc(carro, carrosdafilial);
                    placacarro(carro);
                    restofichacarro(carro);
                    break;

            case 3:
                    scanf("%d", &numeroc);
                    printf(" PLACA: %s", carro[numeroc].placa);
                    printf(" MARCA: %s", carro[numeroc].marca);
                    printf(" MODELO: %s",carro[numeroc].modelo);
                    printf(" FILIAL %d: %s", carro[numeroc].filialloc[1], carrosdafilial[carro[numeroc].filialloc[1]].nomef);

                  break;
            case 4:
                    criarfiliais(carrosdafilial);
                    *pfiliais+=1;
                    break;
          }




        } while(escolha!=6);
          return(0);
        }

 

Link para o comentário
Compartilhar em outros sites

O problema está nesta linha do seu código:

 

 

carrosdafilial[identificador].identificadorcarros[carrosdafilial[identificador].numerodecarros[0]]=ncar;

 

 

O erro de segmentation fault que foi relatado ocorre devido a uma tentativa de acesso a uma array por um índice inválido (index out of bounds). Perceba que a variável array carrosdafilial não é inicializada, fazendo com que seus valores sejam imprevisíveis logo no começo do programa F5Rua4D.gif.

 

 

 

Por exemplo, o dado específico numerodecarros[0] é mexido em somente duas funções do seu código: criarfiliais e filiaisc. A primeira função, que deveria preparar a array de structs carrosdafilial, porém, não trabalha com carrosdafilial[0]. Quando na segunda função o usuário tenta acessar o índice carrosdafilial[0].numerodecarros[0], ocorre o erro de tempo de execução.

 

 

 

Espero ter ajudado GbhmuXl.gif.

Link para o comentário
Compartilhar em outros sites

Consegui, valeu ehhe. Só tenho mais um problema, eu digito o cpf do cliente [0], ai tudo certo, mas se dps de fizer isso eu criar uma nova filial, o cpf que era 08751220946 vira 08751020946, não to entendendo o motivo disso, já q n relaciona.

 

EDIT- Descobri que parte do código tá dando problema

 

 void criarfiliais(filial carrosdafilial[nf]){
       int zero=0;
       carrosdafilial[nf].numerodecarros[0]=0; //Isso tá zuando o cpf, não sei porque, mas quando eu tiro, funciona normalmente.
       printf("\n Digite a localização da filial: ");
       fgets(carrosdafilial[nf].nomef,50,stdin);
       printf("\n\nFilial %s cadastrada com sucesso. O Número de identificação da filial é: %d\n", carrosdafilial[nf].nomef, nf );

     }

Eu preciso que essa função numero de carros em 0, tenha o valor 0 pra iniciar, tem como eu definir isso lá em cima na estrutura?

Link para o comentário
Compartilhar em outros sites

Para inicializar a array carrosdafilial, você teria que alterar esta linha:

 

 

filial carrosdafilial[nf];

 

 

A alteração a seguir faria todos os bits das estruturas de dados serem zerados F5Rua4D.gif:

 

 

filial carrosdafilial[nf] = {0};

 

 

O código abaixo faria o mesmo, mas mudando a alocação para o tipo estático:

 

 

static filial carrosdafilial[nf];

 

* Técnica inválida para arrays de tamanho variável.

 

 

Para zerar somente as arrays numerodecarros internas das structs, você teria que fazer um loop mesmo:

 

 

//A função 'memset' encontra-se em 'string.h'.
for(int i = 0; i < nf; i++)   memset(carrosdafilial[i].numerodecarros, 0, 5 * sizeof(int));

 

 

 

Espero ter ajudado GbhmuXl.gif.

Link para o comentário
Compartilhar em outros sites

Consegui, valeu hehe. Só mais uma duvida, quando eu pegar um string e imprimo ela, sempre sai com o enter, ou seja, pula linha depois que eu imprimo a string, usei scanf quando é só uma palavra, mas quando não é não sei o que fazer.

                          

Link para o comentário
Compartilhar em outros sites

Corrigindo, você não poderia usar a técnica do static que mencionei, pois ela não funciona com VLAs (arrays de tamanho variável) F5Rua4D.gif.

 

 

 

O problema do caractere '\n' pode ser pela presença dele em uma chamada do printf. Também é possível que seja um excesso nos buffers de I/O, o que pode ser resolvido substituindo todo uso de scanf por fgets.

 

 

 

Espero ter ajudado GbhmuXl.gif.

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...