K
KeDaiv
Hi,
ich versuche seit ca einer Woche C zu lernen. Und habe mir dabei mal als Ziel gesetzt eine möglichst dynamische und leicht zu nutzende Liste zu schreiben. Zur Zeit ist dies noch nicht allzuweit vorangeschritten. Jedoch funktionieren erst einmal alle Funktionen wie ich will.
Nun zu meinem Prblem, welches ich erkannt habe, Ich nutze void - Zeiger um auf die gespeicherten Elemente zu zeigen. Den Speicher für die Elemente reserviere ich ebenfals n der Liste. Da es sich nun aber um void Zeiger handelt, kann ich ja alles mögliche darin speichern. Wenn nun eine Struktur in der Liste gespeichert wird, die einen Zeiger auf irgendein anderes Element hat, und ich den Knoten, worin das Element gespeichert ist lösche, dann würde ich auch den Speicherplatz frei räumen. Nun ist es aber dann so, dass ich ein den Speicher, auf den eine Variable in der Struktur zeigte nicht frei geräumt habe. Spontan würden mir da Funktionszeiger einfallen, die ich beim Löschen nutzen könnte. So müsste der Anwender selbst eine Funktion implementieren, die dann den Speicher auf den die Struktur zeigt frei räumen. Jedoch kenne ich Funktionszeiger nur aus C# wo sie als delegates bekannt sind und weiß nicht so genau wie ich einen Funktionszeiger als parameter einer Funktion deklarieren kann. Die andere Frage für mich wäre, ob es andere Möglichkeiten/Strategien gibt um solch ein Problem zu lösen. Denn ich möchte, dass der Anwender möglichst wenig zu tun hat. Von daher möchte ich das gesammte freiräumen in der Liste übernehmen. Ich hoffe dasd das geht und danke euch schon mal für eure Beiträge. Im Anschluss noch mal mein bisheriger Quellcode... ^^
klist.h
klist.c
ich versuche seit ca einer Woche C zu lernen. Und habe mir dabei mal als Ziel gesetzt eine möglichst dynamische und leicht zu nutzende Liste zu schreiben. Zur Zeit ist dies noch nicht allzuweit vorangeschritten. Jedoch funktionieren erst einmal alle Funktionen wie ich will.
Nun zu meinem Prblem, welches ich erkannt habe, Ich nutze void - Zeiger um auf die gespeicherten Elemente zu zeigen. Den Speicher für die Elemente reserviere ich ebenfals n der Liste. Da es sich nun aber um void Zeiger handelt, kann ich ja alles mögliche darin speichern. Wenn nun eine Struktur in der Liste gespeichert wird, die einen Zeiger auf irgendein anderes Element hat, und ich den Knoten, worin das Element gespeichert ist lösche, dann würde ich auch den Speicherplatz frei räumen. Nun ist es aber dann so, dass ich ein den Speicher, auf den eine Variable in der Struktur zeigte nicht frei geräumt habe. Spontan würden mir da Funktionszeiger einfallen, die ich beim Löschen nutzen könnte. So müsste der Anwender selbst eine Funktion implementieren, die dann den Speicher auf den die Struktur zeigt frei räumen. Jedoch kenne ich Funktionszeiger nur aus C# wo sie als delegates bekannt sind und weiß nicht so genau wie ich einen Funktionszeiger als parameter einer Funktion deklarieren kann. Die andere Frage für mich wäre, ob es andere Möglichkeiten/Strategien gibt um solch ein Problem zu lösen. Denn ich möchte, dass der Anwender möglichst wenig zu tun hat. Von daher möchte ich das gesammte freiräumen in der Liste übernehmen. Ich hoffe dasd das geht und danke euch schon mal für eure Beiträge. Im Anschluss noch mal mein bisheriger Quellcode... ^^
klist.h
Code:
/*
* klist.h
*
* Created on: 29.09.2008
* Author: KeDaiv
*/
#ifndef KLIST_H_
#define KLIST_H_
#ifndef NULL
#define NULL (void *)0
#endif
typedef struct ListNode {
void *element;
struct ListNode *next;
} ListNode;
typedef struct List {
size_t type;
int count;
int capacity;
ListNode *first;
} List;
#endif /* KLIST_H_ */
klist.c
Code:
/*
* klist.c
*
* Created on: 29.09.2008
* Author: KeDaiv
*/
#include <stdlib.h>
#include <string.h>
#include "klist.h"
/**
* listInit initialisiert eine Liste mit den Standartwerten
* Es wird ein Zeiger auf die Lieste zurück gegeben
*/
List *listInit( size_t type ) {
//Alloziiert Speicher für eine neue Liste
List *newList = ( List * ) malloc( sizeof(List) );
//Standartwerte werden gesetzt
newList->capacity = 0;
newList->count = 0;
newList->type = type;
newList->first = NULL;
//Zeiger der Liste wird gegeben
return newList;
}
/**
* Ein ListenKnoten wird initialisiert. Hierin werden später die Werte gespeichert.
* Ebenfalls wird ein Zeiger zurück gegeben
*/
ListNode *nodeInit( void ) {
//Für Knoten wird Speicher alloziiert
ListNode *newNode = ( ListNode * ) malloc( sizeof(ListNode) );
//Standartwerte werden gesetzt
newNode->element = NULL;
newNode->next = NULL;
//Zeiger wird zurück gegeben
return newNode;
}
/**
* Diese Funktion alloziiert Speicher und kopiert das Element auf welches der void-Zeiger zeigt
* mit der angegebenen Größe in den Speicher
*/
inline void *cpyElement( void *element, size_t size ) {
//Inhalt auf den der void-Zeiger zeigt wird kopiert.
return memcpy( malloc( size ), element, size );
}
/**
* Der Wert auf den der Zeiger element zeigt wird an die Liste angehängt
*/
void add( List *list, void *element ) {
//Wenn kein erstes Element bereit steht
if( NULL == list->first ) {
//Wird ein erster Knoten angelegt
list->first = nodeInit();
}
//Erster Knoten ist der Ausgangspunkt
ListNode *node = list->first;
//Solange wie Elemente in den Knoten vorhanden sind
while( NULL != node->element ) {
//Wenn es kein Folgeknoten gibt
if( NULL == node->next ) {
//wird einer angelegt
node->next = nodeInit();
}
//Es wird weiter durch die Liste iteriert
node = node->next;
}
//Wenn ein leeres Element gefunden wurde, wird es gesetzt
node->element = cpyElement( element, list->type );
}
/**
* Fügt ein Element am index an. Alle anderen Elemente werden
* jedoch um einen Wert nach hinten verschoben
*/
void insert( List *list, int index, void *element ) {
if( 0 == index ) {
ListNode *newNode = nodeInit();
newNode->element = cpyElement( element, list->type );
newNode->next = list->first;
list->first = newNode;
return;
}
ListNode *node = list->first;
while( 1 < index ) {
index = index - 1;
if( NULL == node->next ) {
node->next = nodeInit();
}
node = node->next;
}
ListNode *newNode = nodeInit();
newNode->element = cpyElement( element, list->type );
newNode->next = node->next;
node->next = newNode;
}
int main( void ) {
List *meineListe = listInit( sizeof(char) );
char *vieleElemente = malloc( sizeof(char) );
*vieleElemente = 'A';
add( meineListe, vieleElemente );
*vieleElemente = 'B';
add( meineListe, vieleElemente );
*vieleElemente = 'C';
add( meineListe, vieleElemente );
*vieleElemente = 'X';
insert( meineListe, 1, vieleElemente );
*vieleElemente = 'Y';
insert( meineListe, 0, vieleElemente );
*vieleElemente = 'Z';
insert( meineListe, 10, vieleElemente );
return EXIT_SUCCESS;
}