2dimensionale Liste: free()

04/17/2015 18:46 Belur#1
Hey,

ich habe zur Zeit eine Aufgabe für die Uni, in der ich eine eigene Shell schreiben muss.

Hab mir das so überlegt, dass ich praktisch eine 2dimensionale verkettete Liste habe.
Benutze dafür folgende structs:
Code:
struct node{
    struct node *next;
    struct node *prev;
    struct argument *nextArg;
    int status;

};

struct argument{
    char *text;
    struct argument *nextArg;
};
Das ganze haben wir uns so gedacht, dass die Befehle in der node-Liste gespeichert werden (bislang sind nur built-in Funktionen wie "exit", "kill", "cd", "echo" etc implementiert) und die jeweiligen Argumente dazu in der argument-Liste.

Das ganze klappt auch ganz gut bis auf das freigeben des Speichers.
Ich hatte es erst so versucht:
Code:
void freeList(struct node *root){
    struct node *tmp = root;
        while ((tmp = tmp->next) != NULL) {
            struct argument *tmpArg = tmp->nextArg;
            struct argument *delArg = tmpArg;
            while (tmpArg != NULL) {
                tmpArg = tmpArg->nextArg;
                free(delArg);
                delArg=tmpArg;
            }
            free(root);
            root=tmp;
        }
}
Die "next" Pointer werden mit NULL initialisiert also besteht kein Risiko, dass die irgendwo in den Speicher zeigen und somit die Schleife nicht durchläuft oder so.

Allerdings klappt die Funktion nicht so ganz. Nach ein paar Befehlen in meiner Shell kommt dann irgendwann ein Speicherzugriffsfehler. Scheint ziemlich Random zu sein. Konnte zmdst keine Regelmäßigkeit erkennen.

Vllt kann mir jemand helfen, wie man so eine "2D Liste" gut "freen" kann.

Grüße
04/17/2015 19:06 snow#2
Ich weiß nicht, ob ich es gerade einfach verpeile, aber warum nicht so simpel?

Code:
void free_arg(struct argument *arg)
{
	while (arg != NULL)
	{
		struct argument *tmp = arg;
		arg = arg->next;
		free(tmp);
	}	
}

void free_node(struct node *root)
{
	while (root != NULL)
	{
		free_arg(root->nextArg);
		
		struct node *tmp = root;
		root = root->next;
		free(tmp);
	}
}
Du musst rein von der Logik her halt durch die Liste, für jeden Eintrag erst nextArg behandeln, dann root in eine zweite Variable abspeichern und root neu zuweisen, danach die zweite Variable mit free() verwenden.
04/18/2015 12:05 Belur#3
Hey, scheint einwandfrei zu funktionieren.
Dankeschön :awesome: