Jump to content
Sign in to follow this  
Tiagovsky

Leitura de Ficheiro

Recommended Posts

Tiagovsky

Boa noite,

Espero que haja algum craque ou nem tanto em C que me possa ajudar.

É o seguinte, eu tenho que fazer uma leitura de um ficheiro txt que contém arcos de um grafo no seguinte formato:

1,2
2,3
3,5
...

Cada linha define um arco entre esses 2 vértices.

Os dados depois são armazenados em AVLs na estrutura de cada vértice.

O que acontece é o seguinte, chega à linha 893 e sem razão aparente, dá segmentation fault :/

Já fui ao ficheiro e apaguei o que estava antes, durante e depois dessa linha e dá sempre segfault na 893, não percebo.

Eu até pensei apagar o que vinha depois, mas são 160000 linhas, isto fica um bocado pobre só com 892.

Alguém que esteja a ver qual é o problema? xD

Muito obrigado de alguém me puder ajudar ;)

Share this post


Link to post
Share on other sites
Localhost

Queres que nós adivinhemos qual é o problema se não dás informação nenhuma nem código?


here since 2009

Share this post


Link to post
Share on other sites
Tiagovsky

Desculpa  😳

A minha função que lê o ficheiro é a seguinte:

int loadConnLocaisTXT(char * filename, HashTable * tab) {
    FILE *file = fopen(filename, "r");
    
    //verificar se foi possivel abrir ficheiro
    if (file == NULL) {
        return 1;
    } else {
        int connCreated = 0;
        char linha[101];
        while (!feof(file)) {
            if (fgets(linha, 100, file) != NULL) {

                int i;
                for (i = 0; i < 101; i++) {
                    if (linha[i] == '\n' || linha[i] == '\r') {
                        linha[i] = '\0';
                        break;
                    }
                }	
                //verificar se local e correctamente inserido
                if (loadLigacao(linha, tab) == 1) connCreated++;
                printf("Conexoes %d\n", connCreated);
			fflush(stdout);
            } else break;
        }
        printf("\n%d Ligacoes Criadas\n", connCreated);
    }
        
    fclose(file);
    return 0;
}

E a função auxiliar loadLigacao é a seguinte:

int loadLigacao(char linha[], HashTable * tab) {
char * id1 = strtok(linha, ",");
char * id2 = strtok(NULL, "\0");
Local local1 = getItem(tab, id1);
Local local2 = getItem(tab, id2);

createConnLocal(local1, local2);

return 1;
}

Acham que coloque a createConnLocal?

Share this post


Link to post
Share on other sites
Tiagovsky

108,14550
108,2555
108,9772
109,16783
109,14876
109,2623             <-
109,15766
109,14207
109,1720
109,17629
109,13826
109,15246

Eu já editei o que lá estava, meti outro arco qualquer, apaguei a anterior, a seguinte, tudo e o erro é sempre nesta linha.

Share this post


Link to post
Share on other sites
Localhost

Estás a fazer alguma chamada recursiva a alguma função?


here since 2009

Share this post


Link to post
Share on other sites
Tiagovsky

Sim, a minha inserção na AVL é recursiva. O algoritmo é:

AVL inserir(Info inf, AVL arv, char* key) {
if( arv == NULL ) {
	arv = malloc(sizeof(struct sAVL));
	strcpy(arv->key, key);
	arv->info = inf;
	arv->alt = 0;
	arv->esq = arv->dir = NULL;
	}
else {
	if( compKeys(key, arv->key) == 2 ) {
		arv->esq = inserir( inf, arv->esq, key);
		if( altura( arv->esq ) - altura( arv->dir ) == 2 ) {
			if( compKeys(key, arv->esq->key) == 2) arv = rotSimplesEsq(arv);
			else  arv = rotDuplaEsq(arv);
		}
	}
	else {
		if( compKeys(key, arv->key) == 1) {
			arv->dir = inserir(inf, arv->dir, key);
			if( altura(arv->dir) - altura( arv->esq ) == 2 ) {
				if(compKeys(key, arv->dir->key) == 1) arv = rotSimplesDir(arv);
				else arv = rotDuplaDir(arv);
			}
		}
	}
}
arv->alt = max(altura(arv->esq),altura(arv->dir)) + 1;
return arv;
}

Share this post


Link to post
Share on other sites
Localhost

O problema encontra-se _provavelmente_ nas demasiadas chamadas recursivas. Como tens muitas inserções e, consequentemente, muitas chamadas recursivas a stack vai encher e vai resultar num stack overflow que te vai causar o segmentation fault.


here since 2009

Share this post


Link to post
Share on other sites
Tiagovsky

Estou a perceber.

Há alguma forma de aumentar a stack?

Ou achas que deva tentar usar um algoritmo iterativo?

O que é estranho é que este é 1 de 2 grafos que o meu trabalho usa, e o 1º tem 360000 linhas para usar e não tem problemas com isso. Já este impanca nessa linha de 160000.

Ambos os grafos têm cerca de 18000 nodos.

Share this post


Link to post
Share on other sites
Localhost

Sempre que puderes escolher entre um algoritmo recursivo e um iterativo escolhe o iterativo. É mais eficiente em termos de tempo de execução e de memória.

Realmente isso é um bocado estranho; de qualquer das formas tenta mudar para o algoritmo iterativo e depois diz qualquer coisa.


here since 2009

Share this post


Link to post
Share on other sites
Surtr

Antes de executar o programa, corre isto na shell, sudo ulimit -s unlimited. Isto faz com que a stack não tenho limite, se estourar na mesma, sabes que não é daí.

Share this post


Link to post
Share on other sites
blackburn69

Boa noite.

Corre o programa no gdb. Tens aqui um tutorial rápido e prático de como usar o gdb para o que pretendes.

Compila com a flag -ggdb no gcc.

Podes correr o programa no valgrind também... pode ser que dê alguma informação útil. Usa printf's também se for necessário para achares o erro.

É que com esse volume de código terá mesmo de ser usando isto.

Vai dando notícias.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.