free Exception beim Löschen aus Liste

Eroli

Erfahrenes Mitglied
Hallo zusammen,

ich möchte Elemente aus einer Liste löschen. Die Liste sieht so aus:

(Soll übrigens C und nicht C++ sein)
C:
struct node
{
	struct node *prev;
	struct node *next;
	char *title;
	struct node *list;
};

Ich will damit ein Menü mit eventuellen Untermenüs aufbauen, daher die list in der liste.

Löschen sieht so aus:

C:
void deleteNode(struct node *list, struct node *node)
{
	struct node *it = list;
	while (it->next != NULL)
	{
		if (it == node)
		{
			if (it == list)
			{
				if (it->next != NULL)
					it->next->prev = NULL;
				list = it->next;
				free(it);
				break;
			}
			else if (it == node)
			{
				it->prev->next = it->next;
				it->next->prev = it->prev;
				free(it);
				break;
			}
		}
		it = it->next;
	}
}

Allerdings wird beim free (bei beiden) immer eine Speicherschutzverletzung geworfen und ich komme nicht wirklich darauf, wieso?

Was meint ihr?

EDIT: Wenn ich das free auskommentiere, dann ist das Element auch weg, daher nehme ich an, dass der Algo stimmen sollte. Kann es sein, dass Windows7 beim free streikt?
 
Zuletzt bearbeitet:
Hi.

Mach mal ein vollständiges Minimal-Beispielprogramm.

Allerdings, wenn du den Knoten, den du löschen willst, schon hast, dann brauchst du ihn doch in der Liste nicht mehr suchen...

Eroli hat gesagt.:
Kann es sein, dass Windows7 beim free streikt?
Nein. PEBKC ;)

Gruß
 
Zuletzt bearbeitet:
Stimmt, wenn ich ihn schon habe, ist das unnötig.

Aber falls ich das später mal umstellen will, um einen Knoten mit einem bestimmten title zu finden, dann muss ich das ja schon so machen.

Beispielprogramm:
C:
#include <stdio.h>
#include <stdlib.h>
#include "MenuList.h"

typedef struct node node;

node *head;
node *current;

int main()
{
	int i = 0;
	head = newList(head, "0");

	head = appendNode(head, "1");
	head->next->list = newList(head->next->list, "11");
	head->next->list = appendNode(head->next->list, "12");
	head = appendNode(head, "2");
	head = appendNode(head, "3");

	printf("hello\n");

	current = head;
	while (current != NULL)
	{
		printf(current->title);
		current = current->next;
		printf("\n");
	} 

	deleteNode(head, head->next);

	current = head;
	while (current != NULL)
	{
		printf(current->title);
		current = current->next;
		printf("\n");
	} 
}

In der Delete-Funktion ist noch nicht berücksichtigt, dass eine Liste Unterlisten haben kann.

EDIT: Falls du das Ganze selber debuggen willst, dann kann ich dir auch eben den kompletten Quelltext posten - oder meintest du das eben etwa schon?
 
Zuletzt bearbeitet:
Hallo Eroli,

Dein Problem ist, dass du nicht genügend Speicher allozierst.
C:
struct node* newList = (struct node*)malloc(sizeof(struct node*));
// und
struct node *newNode = (struct node*)malloc(sizeof(struct node*));

Damit allozierst du lediglich Platz für einen Zeiger auf einen Node, jedoch nicht für einen ganzen Node. Hätte malloc einen konkreten Rückgabetyp (wie new in C++) wäre es dann auch (struct node**). Ergo musst du deinen Node folgendermassen allozieren:
C:
struct node* newList = (struct node*)malloc(sizeof(struct node));
// und
struct node *newNode = (struct node*)malloc(sizeof(struct node));

Gruss
Muepe
 
Hi.

Du allozierst nicht genug Speicher.

Statt
C:
malloc(sizeof(struct node*));
muss es heißen
C:
malloc(sizeof(struct node));

\edit: Ups, zu spät...

Desweiteren ist dein Code zu kompliziert und aufgebläht.
C:
Bool isEmpty(struct node *list)
{
	return (list->next == NULL);
}
Den ersten Parameter der newList brauchst du nicht (verwendest du ja auch gar nicht). In der appendNode Funktion kannst du die newList Funktion wiederverwenden, du prüfst Bedingungen oft doppelt ab:
C:
if (it == node) // <<< [1]
{
   if (it == list)
   {
   }
   else if (it == node) // <<< das ist schon klar, siehe [1]
   {
   }
}
Wobei die Prüfung ob "it == list" ist auch wegfallen kann, da dies nur ein Spezialfall von "it == node" ist.

Gruß
 
Zuletzt bearbeitet:
Oh man, da hätte ich eigentlich selber drauf kommen können....

Vielen Dank euch beiden.

Ich werde den Code verbessern, das war alles nur in Eile runtergeschrieben...
 

Neue Beiträge

Zurück