Ir ao conteúdo
  • Cadastre-se

C Runtime error em só um compilador específico


Thiago Rosario

Posts recomendados

Boa tarde, tô com um problema desde ontem que não consigo resolver. Tenho que implementar um grafo orientado em C(implementação em matriz de ajdacência), onde o usuário digita a quantidade de nós e a quantidade de arestas entre eles e eu então tenho que listar os nós e dar a informação de cada um, e ele funciona normalmente no codeblocks ou em qualquer outro compilador online. Mas por algum motivo no sharif judge, que é o compilador que minha faculdade usa, ele acusa runtime error. Eu já tentei mudar múltiplas coisas, mas ele simplesmente não aceita. O código em questão é este:

#include <stdio.h>
#include <stdlib.h>
#define MAX 10000

typedef struct item{
int indice;
int depende;
int ajuda;
}item;

typedef struct tipolista{
item sequencia[100];
int quantidade;
}tipolista;

typedef struct tipomatriz{
tipolista lista;
int adjacente[MAX][MAX];
}tipomatriz;

void iniciar(tipomatriz *matriz){
    int i,j,aux;
    matriz->lista.quantidade=0;
    aux=0;
    while(aux<100){
        matriz->lista.sequencia[aux].ajuda=0;
        matriz->lista.sequencia[aux].depende=0;
        aux++;
    }

    for(i=0;i<MAX;i++){
        for(j=0;j<MAX;j++)
            matriz->adjacente[i][j]=0;

    }
}

void inserir(tipomatriz *matriz,int a){
    matriz->lista.sequencia[matriz->lista.quantidade].indice=a;
    matriz->lista.quantidade++;
}

void criar_aresta(tipomatriz *matriz, int a, int b){
    int x,y;
    x=a-1;
    y=b-1;
    matriz->adjacente[x][y]=1;
    matriz->lista.sequencia[x].depende++;
    matriz->lista.sequencia[y].ajuda++;
}

void imprimirteste(tipomatriz *matriz){
    int i,j;

    for(i=0;i<matriz->lista.quantidade;i++){
        j=0;
        if(i!=0)
            printf("\n");
        printf("%d %d %d",matriz->lista.sequencia[i].indice,matriz->lista.sequencia[i].ajuda,matriz->lista.sequencia[i].depende);
        while(j<=matriz->lista.sequencia[i].depende){
            if(matriz->adjacente[i][j]==1)
                printf(" %d",matriz->lista.sequencia[j].indice);
            j++;
        }
    }

}

int main()
{
    int a,b,aux,aux2;
    tipomatriz *matriz=(tipomatriz*)malloc(sizeof(tipomatriz));
    iniciar(matriz);

    scanf("%d%d",&a,&b);

    for(aux=0;aux<a;aux++){
        aux2=aux+1;
        inserir(matriz,aux2);
    }

    for(aux=0;aux<b;aux++){
        scanf("%d %d",&aux2,&a);
        criar_aresta(matriz,aux2,a);
    }

    imprimirteste(matriz);

    return 0;
}

Se alguém puder me dar uma luz eu realmente apreciaria. Meu professor não ajuda em tarefas e os monitores não conseguiram resolver.

Link para o comentário
Compartilhar em outros sites

34 minutos atrás, Thiago Rosario disse:

Mas por algum motivo no sharif judge, que é o compilador que minha faculdade usa, ele acusa runtime error

 

Esse sharif judge não é um compilador. É só mais uma ferramenta dessas de "programming contest". Aparentemente usa gcc como compilador. Veja com sua escola qual a versão de gcc que eles usam na máquina em que instalaram isso. É o mínimo que eles podem fazer. E use a mesma versão em sua máquina, claro. Se eles não puderem fazer isso ou não souberem o que eu lamentaria pela sua escola, instrutores e monitores.

 

Provavelmente seu programa tem erros mesmo. Pode estar compilando em debug mode que é mais permissivo e assim não dá erro. Pode estar usando opções de otimização diferentes que as do compilador da escola...

 

Isso é muito comum.

 

 

Code::Blocks também não é um compilador. É apenas um IDE --- sim, IDE é masculino --- e bem ruim dentre tantas opções hoje em dia e sem custo. A única pior seria o Dev-C++. Eu não conhecia isso mas vim a conhecer aqui no forum.

 

Vou ver seu programa depois

Ao postar um programa como esse, ou mesmo ao discutir com alguém o problema, se acostume a documentar melhor as coisas. Ou a documentar de algum modo.

 

Forneça um ou mais grupos de valores de entrada e o o resultado que esperava obter com tais dados. Ajude s  outros a ajudar você você.

 

Seu programa não parece bom. Não tem um único comentário, não tem qualquer mensagem orientando a leitura, o cursor apenas fica lá piscando... Pense nisso.

 

E SEMPRE teste o retorno de scanf(). É o básico do básico: é ingenuo seguir sem saber se leu algo. Vai calcular a partir de que?

 

E entenda que é muito mais simples ler dados de um arquivo do que ficar parado digitando a cada teste. 

 

E num primeiro momento use constantes. É muito mais fácil.

 

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

@arfneto Eu agradeço os comentários. Então, esse código não é final, eu costumo comentar no fim pro professor entender melhor depois, mas você tem razão, eu deveria ter esclarecido melhor a saída e entrada. Eu também sei que o code blocks e o sharif não são compiladores, eu só quis me referir aos compiladores dos mesmos.

 

Então, a entrada do algoritmo é pra ser o número de pacotes a ser instalado em um sistema e o número N de dependências entre os mesmos(as arestas). Nas próximas N linhas o usuário vai digitar o números dos pacotes A B, onde A vai depender de B(ou seja, vai ter uma aresta não orientada apontando para B).

A saída seria uma lista com os índices dos pacotes seguidos pelo número de dependentes, depois o número de dependênicias, e o índice das dependências. Um exemplo simples seria:

Entrada:

2 1

1 2

Saída:

1 0 1 2

2 1 0

Ou seja, o pacote um tem zero dependentes, tem uma dependência, e essa dependência é o pacote 2. O pacote 2 tem um dependente e 0 dependências.

 

Outra coisa que eu não clarifiquei bem foi que eu teste este programa em múltiplos compiladores. Nenhum deles deu problema apenas aquele que é usado no sharif judge. Eu procurei por erros comuns e dei printf em múltiplos pontos do código, mas o erro persiste. O problema é que eu não sei nem mesmo o que o problema significa e o que pode estar causando o mesmo.

 

E sobre o ponto do cursor piscando, isso é requerimento. O programa não pode ter nenhuma mensagem pro usuário, somente a saída.

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

13 minutos atrás, Thiago Rosario disse:

Eu também sei que o code blocks e o sharif não são compiladores, eu só quis me referir aos compiladores dos mesmos.

 

 

Entendo. Mas num mundo sério você precisaria saber qual a versão de gcc usada no sharif na universidade e as opções de compilação em uso lá, para poder ter mais flexibilidade e garantia usando a mesma versão na sua máquina durante o desenvolvimento. E poderia ter dito aqui a menos uma das versões que usou para teste em sua máquina e como compilou

 

16 minutos atrás, Thiago Rosario disse:

eu costumo comentar no fim pro professor entender melhor depois, mas você tem razão, eu deveria ter esclarecido melhor a saída e entrada

 

Antes de tudo comente o código para você mesmo. Daqui a uns dias pode não estar certo do porque de algo que escreveu, e nem todos os seus programas vão ser assim simples

 

17 minutos atrás, Thiago Rosario disse:

E sobre o ponto do cursor piscando, isso é requerimento. O programa não pode ter nenhuma mensagem pro usuário, somente a saída

 

O requerimento só envolve o programa como submetido à plataforma. Então depois que ele estiver funcionando você tira essas coisas.

 

A lógica é que ao usar algo mais dinâmico para testar, como um arquivo, e usar prompts para ler e para mostrar o que leu antes de ficar calculando você termina seu programa muito, mas muito antes. E aí com o tempo que sobra você pega uns minutos e passa a ler do teclado e omite os prompts. E envia para a plataforma. :) 

 

Em relação a mensagens de saída, pode ser que a plataforma simplesmente desconsidere a saída de erro, e então você pode usar a vontade. Seria o mínimo de se esperar de uma plataforma para estudantes afinal. Rodar o programa com
 

	programa 2 > /dev/null

 

simplesmente descarta tudo que se escrever em stderr e é prática comum durante testes de programas, junto com usar assert() para mostrar mensagens dentro do programa. Ao invés de gravar em stdout se grava em stderr as mensagens de teste e basta compilar em modo release que os assert() ambém vão sumir e redirecionar stderr para /dev/null que as mensagens de teste também somem.

E Então você pode conviver por mais tempo com código de teste no meio do programa de produção.

 

Seu programa não está nada bom. Não sei se a plataforma vai entrar no mérito de como escreveu mas se acha que vão ler mesmo o código talvez devesse atentar para umas coisas que tem lá. Um grupo de revisão de código não deixaria passar e se os monitores fazem isso você pode perder nota. Se for importante escreva e eu te falo algumas coisas.

 

Exemplo: construções como essa são condenadas e proibidas em muitas empresas e escola desde os anos '80. Só não era proibido antes porque a linguagem demorou para evoluir:

 

   int i, j;

    for (i = 0; i < matriz->lista.quantidade; i++) {
        j = 0;
 

 

NUNCA se deixa variáveis com nomes ingenuos como i e j com escopo global para a função ou muito menos para o programa TODO, como as meigas aux e aux2 em seu programa

 

  • um typedef em geral é conhecido por ter a primeira letra em maiúscula em C ou C++. É prática comum e esperada. Começar os typedef por "tipo" é verboso demais e seria condenado em qualquer comitê de revisão de código
  • TESTE o retorno de scanf(). Não tem sentido não testar

  • typedefs como esse
    typedef struct tipolista {
        item sequencia[100];
        int quantidade;
    }tipolista;

     

não passariam. A estrutura pode muito bem ser anônima já que não há referências internas a ela mesma. Prefira o simples
 

typedef struct
{
    int  quantidade;
    Item sequencia[100];

}	Lista;

 

Como os IDE modernos em geral usam também cores veja como fica mais legível se usar a convenção popular e se separar uma linha em branco para destacar o nome do typedef:

image.png.908198474172fb570f89ecc952f944d9.png

 

E fica claro que Item e Lista são typedef e Lista contem Item. Claro, pode não concordar :) 

 

  • main() deve ser a primeira função de seu programa, se possível em um arquivo separado
     
  • isso aqui é um problema maior:
     
    void criar_aresta(tipomatriz* matriz, int a, int b)
    {
        int x, y;
        x = a - 1;
        y = b - 1;
        matriz->adjacente[x][y] = 1;
        matriz->lista.sequencia[x].depende++;
        matriz->lista.sequencia[y].ajuda++;
    }

é uma consequência do que já expliquei mas entenda que main() começa assim em seu programa:
 

int main()
{
    int a, b, aux, aux2;
    tipomatriz* matriz = (tipomatriz*)malloc(sizeof(tipomatriz));


E então tem uma variável global com o nome de a e essa função tem um parâmetro chamado a que vai ocultar aquela variável global. Isso é um pesadelo em termos de manutenção e não passaria em lugar nenhum

 

  • esse loop também não:
        for (aux = 0; aux < a; aux++) {
            aux2 = aux + 1;
            inserir(matriz, aux2);
        }


    aux2 = aux + 1?  Sério? Use nomes mais expressivos

 

Sobre seu programa
 

    printf("sizeof MATRIZ = %zdK Megabytes\n\n",
        sizeof(tipomatriz) / 1024 / 1024 );


em seu programa você veria que cada matriz tem nada menos que 381 megabytes. Pode ser que sua plataforma não permita tal uso e cancele seu programa...

 

 

 

 

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

Crie uma conta ou entre para comentar

Você precisa ser um usuário 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 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...