Elnisky
Elnisky

Reputation: 13

SIGTRAP when freeing first element of a Queue

I'm in trouble, everytime my function calls "desenfileirar" I had some breakpoints. Can anyone help me? I need to print a bidimensional array that means the path traveled by an ant. It needs to start at (0,0) and reach to (9,9). That I get success, only using the "handle SIGTRAP nostop" command at debugger. I implemented the BFS algorithm, but I'm unsuccessful at dequeue the elements. It means a memory violation, I believe

Program received signal SIGTRAP, Trace/breakpoint trap.
In ntdll!TpWaitForAlpcCompletion () (C:\Windows\system32\ntdll.dll)
In ntdll!RtlLargeIntegerDivide () (C:\Windows\system32\ntdll.dll)
In ntdll!RtlCopyExtendedContext () (C:\Windows\system32\ntdll.dll)
#10 0x004014cd in desenfileirar (F=0x28fe74) at I:\Exercício-1\Formiga.c:60
I:\Exercício-1\Formiga.c:60:1306:beg:0x4014cd
At I:\Exercício-1\Formiga.c:60

here's the code:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "Fila.h"

struct st_no{
    int linha; //coordinate from array line
    int coluna; //coordinate from array column
    int plinha; //coordinate from the generator of line (father)
    int pcoluna; //coordinate from the generator of column (father)
    FILA *prox;
};

void geraFilhos(FILA **Q, FILA **gerador, short int *matriz[N][N], int *visitados[N][N]);
void print_shortest_path(FILA **F, FILA **src, FILA **dst);

/**=========================== FUNÇÕES DA FILA ===========================**/
bool vazia(FILA **F){
    return *F == NULL;
}

void criar(FILA **F){
    *F = NULL;
}

void enfileirar(FILA **F, int i, int j, int paiI, int paiJ){
    FILA *novo, *P;
    novo = (FILA *)malloc(sizeof(FILA*));
    novo->linha = i;
    novo->coluna = j;
    novo->plinha = paiI;
    novo->pcoluna = paiJ;
    novo->prox = NULL;

    if(*F == NULL)
        *F = novo;
    else{
        P = *F;
        while(P->prox != NULL)
            P = P->prox;
        P->prox = novo;
    }
}

FILA *desenfileirar(FILA **F){
    FILA *P, *ret = (FILA*)malloc(sizeof(FILA));
    if(vazia(F)){
        return NULL;
    }
    else{
        P = *F;
        ret->linha = P->linha;
        ret->coluna = P->coluna;
        ret->plinha = P->plinha;
        ret->pcoluna = P->pcoluna;
        ret->prox = NULL;
        *F = (*F)->prox;
        free(P); // HERE I HAD THE BREAKPOINTS
    }
    return ret;
}

FILA *buscar(FILA **L, int i,int j){
    FILA *P;

    P = *L;
    while(P != NULL){
        if(P->linha == i && P->coluna == j)
            return P;
        P = P->prox;
    }
    return NULL;
}

void imprimir(FILA **F){
    FILA *P;

    P = *F;
    printf("Fila:\n");
    while(P != NULL){
        printf("(%i,%i)", P->linha, P->coluna);
        printf("(%i,%i)\n\n", P->plinha, P->pcoluna);
        P = P->prox;
    }
}

FILA *atribuicao(FILA **F, int i, int j){
    FILA *aux = (FILA*)malloc(sizeof(FILA));
    aux->linha = i;
    aux->coluna = j;
    aux->prox = NULL;
    *F = aux;
    return *F;
}

/**=========================== FUNÇÕES QUE ACHAM O CAMINHO ===========================**/

void caminhar(short int *matriz[N][N], FILA *inicio,FILA *objetivo){
    FILA *abertos, *x, *fechado;
    int i, j, *visitados[N][N];

    criar(&abertos);
    criar(&fechado);

    for(i = 0; i < N; i++){
        for(j = 0; j < N; j++){
            visitados[i][j] = 0;
        }
    }

    inicio->plinha = -1;
    inicio->pcoluna = -1;
    enfileirar(&abertos,inicio->linha,inicio->coluna,inicio->plinha,inicio->pcoluna);
    while(!vazia(&abertos)){
        x = desenfileirar(&abertos);
        enfileirar(&fechado,x->linha,x->coluna,x->plinha,x->pcoluna);
        if(x->linha == objetivo->linha && x->coluna == objetivo->coluna){
            printf("Parou aqui!\n\n\n");
            break;
        }
        else{
            geraFilhos(&abertos,&x,matriz,visitados);
            visitados[x->linha][x->coluna] = 1;
        }
    }
    imprimir(&fechado);
    print_shortest_path(&fechado,&inicio,&objetivo);
}

void geraFilhos(FILA **Q, FILA **gerador, short int *matriz[N][N], int *visitado[N][N]){
    FILA *P = *gerador;

    if((P->coluna+1 < N)&&(matriz[P->linha][P->coluna+1] == 0) && (visitado[P->linha][P->coluna+1] == 0)){//direita
        P->plinha = P->linha;
        P->pcoluna = P->coluna;
        P->coluna++;
        enfileirar(Q,P->linha,P->coluna,P->plinha,P->pcoluna);
        P->coluna--;
    }
    if((P->linha+1 < N)&&(matriz[P->linha+1][P->coluna] == 0) && (visitado[P->linha+1][P->coluna] == 0)){//baixo
        P->plinha = P->linha;
        P->pcoluna = P->coluna;
        P->linha++;
        enfileirar(Q,P->linha,P->coluna,P->plinha,P->pcoluna);
        P->linha--;
    }
    if((P->coluna-1 >= 0)&&(matriz[P->linha][P->coluna-1] == 0) && (visitado[P->linha][P->coluna-1] == 0)){//esquerda
        P->plinha = P->linha;
        P->pcoluna = P->coluna;
        P->coluna--;
        enfileirar(Q,P->linha,P->coluna,P->plinha,P->pcoluna);
        P->coluna++;
    }
    if((P->linha-1 >= 0)&&(matriz[P->linha-1][P->coluna] == 0) && (visitado[P->linha-1][P->coluna] == 0)){//cima
        P->plinha = P->linha;
        P->pcoluna = P->coluna;
        P->linha--;
        enfileirar(Q,P->linha,P->coluna,P->plinha,P->pcoluna);
        P->linha++;
    }
}

void print_shortest_path(FILA **F, FILA **src, FILA **dst){
    FILA *P, *Q;
    Q = *F;
    printf("CAMINHO: \n\n\n");

    printf("(%d,%d)\n", (*dst)->linha,(*dst)->coluna);
    while((*dst)->linha != (*src)->linha && (*dst)->coluna != (*src)->coluna){
        P = buscar(&Q,(*dst)->linha,(*dst)->coluna);
        printf("(%d,%d)\n", P->plinha,P->pcoluna);
        (*dst)->linha = P->plinha;
        (*dst)->coluna = P->pcoluna;
    }
    printf("(%d,%d)\n", (*src)->linha,(*src)->coluna);
}

/**=========================== MAIN ===========================**/

#include <stdio.h>
#include <stdlib.h>
#include "Fila.h"

/*
 *
 */
 void caminhar(short int *matriz[N][N], FILA *inicio,FILA *objetivo);

int main(int argc, char** argv) {
FILE *arq = fopen("teste.txt", "r");
    int i, j;
    int tabuleiro[N][N];

    FILA *inicial, *objetivo;

    criar(&inicial);
    criar(&objetivo);

    inicial = atribuicao(&inicial,0,0);
    objetivo = atribuicao(&objetivo,N-1,N-1);

    if(!arq){
        printf("Nao deu pra ler!");
    }else{
        for(i = 0; i < N; i++){
            for(j = 0; j < N; j++){
                fscanf(arq,"%d",&tabuleiro[i][j]);
            }
        }

        printf("INICIO: (0,0)\n");
        printf("OBJETIVO: (%d,%d)\n\n", N, N);

        caminhar(tabuleiro,inicial,objetivo);
    }
    system("PAUSE");
    return (EXIT_SUCCESS);
}

/**=========================== FILA.H ===========================**/

#include <stdlib.h>
#include <stdbool.h>
#define N 10

typedef struct st_no FILA;

void criar(FILA **F);
void destruir(FILA **F);
bool vazia(FILA **F);
void enfileirar(FILA **F, int i, int j, int paiI, int paiJ);
FILA *desenfileirar(FILA **F);
void imprimir(FILA **F);
FILA *atribuicao(FILA **F, int i, int j);

Upvotes: 0

Views: 456

Answers (1)

It would help to have a complete, compilable example, because you provide the source for functions named desenfileirar and caminhar, but you also use functions named criar, enfileirar, vazia, geraFilhos, imprimir, and print_shortest_path, and you use a structure name FILA without providing definition. Also, you never show a malloc() but you show calls to free().

The free() at the beginning of caminhar() is inherently pointless (calling free(NULL) is guaranteed not to do anything, and explicitly setting *f = NULL only if *f is already NULL? Also, I'm sure you'll agree, not helpful), but harmless.

The immediately glaring problem that I see is that your ret is a pointer to a FILA, but you are using it without allocating storage for it. This means that when you enter the desenfileirar() function, a variable named ret is created, with enough storage for a pointer to FILA, but with no explicitly assigned value, and you then treat it as a valid pointer, and write through it. (And then you're returning it, too...) This is Undefined Behaviour, several times over, and fortunately for you, you got lucky enough that this time, it failed during testing. There's more than one possible solution for this, but without seeing your entire program, I don't know which one to recommend. (The likeliest solution, nevertheless, is simply to insert a line reading ret=malloc(sizeof *ret); right before you start using it.)

**UPDATE**

Now that you've posted additional code, here's my further analysis. This appears to be several source files, but it clearly still isn't compilable, and is missing Fila.h.

In enfileirar(), you're using malloc() to allocate enough storage for a pointer to FILA instead of enough storage for a FILA. In desenfileirar(), you have a syntax error on the first line, in the call to malloc(). Also, you have a memory leak if *F==NULL. Don't malloc() storage for ret until you need it. You also have a random 2 on the free() line., and you're forgetting to initialize ret->prox=NULL, which will lead to Undefined Behaviour at some random later point. In atribuicao(), you're forgetting to initialize aux->prox=NULL.

Your problems are almost certainly stemming from the two places where you are forgetting to initialize the prox element of a new FILA. This is because memory returned from malloc() is not blank, the content is indeterminate. So if you don't set prox=NULL, when you walk the list you're going to walk off the end into totally random memory.

Upvotes: 2

Related Questions