Stack-Push-Funktion mit c, implementiert mit doppelt verknüpfter Liste

Aug 30 2020

Ich versuche, den Hierholzer-Algorithmus mit C zu implementieren. Ich habe eine Push-Funktion für einen einfachen Stapel erstellt, der mit einer doppelt verknüpften Liste implementiert wurde, aber der Zeiger bewegt sich immer zur Bedingung else, selbst wenn der Startknoten leer ist.

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<stddef.h>

typedef struct node
{
    int source;
    int num;
    struct node *l, *r;
    int done;
}node;

void push(int source, int num, struct node *head)
{
    node *n = malloc(sizeof(node));
    n->num = num;
    n->l = NULL;
    n->done = 0;
    n->source = source;

    if (*head == NULL)
    {
        head = n;
        head -> r = NULL;
    }
    else
    {
        n -> r = head;
        head->l = n;
        head = n;
    }
}

int pop(node *head)
{
    if(head == NULL)
    {
        return -1;
    }
    else
    {
        node *temp = head;
        head = head->r;
        int num = temp->num;
        free(temp);
        return num;
    }
}

void append(node *extra, node *head)
{
    node *temp = extra;
    while(temp->r != NULL)
    {
        temp = temp->r;
    }
    temp->r = head;
    head->l = temp;
    head = extra;
}

node** read(int num)
{
    char a[2000] = "Assignment1.txt" ,c[1000];


    FILE *f = fopen(a,"r");
    printf("Got file\n");

    node *adj[num];

    int i=0;
    node *l;
    printf("l: %d\n", l);

    while(fscanf(f,"%s",c))
    {

        char *p = strtok(c, ",");
        while(p!=NULL)
        {
            push(i, atoi(p), l);
            p = strtok (NULL, ",");
        }
        adj[i++] = l;
    }
    printf("Adjacency list created\n");

    return adj;
}

node* euler(node *adj[],int n, int i)
{
    node *cpath = NULL;
    node *fin = NULL;
    node *extra;
    node *temp = adj[i];
    node *tempi;

    while(temp!=NULL)
    {
        if(temp->r->r == NULL)
        {
            tempi = temp;
        }

        if(temp->done == 0)
        {
            temp->done = 1;
            push(i, temp->num, cpath);
            extra = euler(adj, n, temp->num);
            append(extra, cpath);
        }
        else
        {
            temp = temp->r;
        }
    }

    while(tempi->l != NULL)
    {
        push(i,tempi->num, fin);
        extra = euler(adj, n, tempi->num);
        append(tempi, fin);
        tempi = tempi->l;
    }
    if(tempi != NULL)
    {
        push(i,tempi->num, fin);
        extra = euler(adj, n, tempi->num);
        append(tempi, fin);
    }

    return fin;
}

int main()
{
    int n;
    printf("Enter the number of vertices: ");
    scanf("%d", &n);
    node **adj = read(n);
    node *fin = euler(adj, n, 0);
    node *temp = fin;

    while(temp!=NULL)
    {
        printf("%d ", temp->num);
        temp = temp->r;
    }

    return 0;
}

Ich muss noch den gesamten Code debuggen, stecke aber bei der Funktion read () fest, bei der die Eingabe eine Assignment1.txt ist, die Folgendes enthält:

2,3
3,1
1,2

Ich kann nicht verstehen, warum ich einen Segmentierungsfehler erhalte.

Antworten

VladfromMoscow Aug 30 2020 at 15:37

Die Funktion behandelt eine Kopie des Wertes des übergebenen Zeigers auf den Kopfknoten. Der ursprüngliche Zeiger selbst wird also in der Funktion nicht geändert. Es ist die Kopie des Werts des übergebenen Zeigers, der innerhalb der Funktion geändert wird.

Sie müssen den Zeiger als Referenz übergeben, die indirekt über den Zeiger auf den Zeiger erfolgt.

Die Funktion kann folgendermaßen deklariert und definiert werden.

int push( struct node **head, int source, int num )
{
    node *n = malloc(sizeof(node));
    int success = n != NULL;

    if ( success )
    {
        n->source = source;
        n->num    = num;
        n->done   = 0;
        
        n->l = NULL;
        n->r = *head;
        if ( *head != NULL ) ( *head )->l = n;

        *head = n;
    }

    return success;
}
Hilmicihan Aug 30 2020 at 14:50

In der Lesefunktion geben Sie adj zurück. Es ist jedoch eine lokale Variable. Sie verwenden keine Malloc-Funktion. Lokale Variablen werden also zerstört, nachdem die Funktion zurückgegeben wurde. Daher versuchen Sie, auf einen zufälligen Ort zuzugreifen, wenn Sie versuchen, auf adj in main zuzugreifen. Ich denke, das Problem wird durch diesen Grund verursacht.