C LinkedList header, current = nullptr

  • C

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von DragonSlayerMarc.

    C LinkedList header, current = nullptr

    Hi,

    ich befasse mich nun seit einiger Zeit mit C. Neulich habe ich mir LinkedLists angesehen und fand diese auch sehr praktisch. Nun habe ich mich heute rangesetzt und wollte einen Header für LinkedLists machen um für mich das verwalten dieser einfacher zu machen.

    Der Header:
    Spoiler anzeigen

    C-Quellcode

    1. #ifndef _LINKEDLIST_H
    2. #define _LINKEDLIST_H
    3. #include <stdlib.h>
    4. typedef struct Node *List;
    5. struct Node
    6. {
    7. List Previous;
    8. char* Key;
    9. char* Data;
    10. List Next;
    11. };
    12. typedef struct Node Node;
    13. void linit(List l, char* key, char* data)
    14. {
    15. l = (List) malloc(sizeof(Node));
    16. l->Previous = NULL;
    17. l->Key = key;
    18. l->Data = data;
    19. l->Next = NULL;
    20. }
    21. void laddstart(List l, char* key, char* data)
    22. {
    23. List Temp = l;
    24. l = (List) malloc(sizeof(Node));
    25. l->Previous = NULL;
    26. l->Key = key;
    27. l->Data = data;
    28. l->Next = Temp;
    29. }
    30. void laddend(List l, char* key, char* data)
    31. {
    32. List current = l;
    33. while (current->Next != NULL)
    34. {
    35. current = current->Next;
    36. }
    37. current->Next = (List) malloc(sizeof(Node));
    38. current->Next->Previous = current;
    39. current->Next->Key = key;
    40. current->Next->Data = data;
    41. current->Next->Previous = NULL;
    42. }
    43. void lremove(List l, char* key)
    44. {
    45. List current = l;
    46. while (current->Key != key)
    47. {
    48. current = current->Next;
    49. }
    50. List Previous = current->Previous;
    51. List Next = current->Next;
    52. free(current);
    53. Previous->Next = Next;
    54. Next->Previous = Previous;
    55. }
    56. void lforeach(List l, void (*func) (char*, char*))
    57. {
    58. List current = l;
    59. while (current->Next != NULL)
    60. {
    61. func(current->Key, current->Data);
    62. current = current->Next;
    63. }
    64. }
    65. #endif



    Und meine Main:
    Spoiler anzeigen

    C-Quellcode

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include "LinkedList.h"
    4. void stringsForEach(char*, char*);
    5. int main()
    6. {
    7. List strings = NULL;
    8. linit(strings, "2", "heiße");
    9. laddend(strings, "3", "nicht");
    10. laddend(strings, "4", "Rüdiger");
    11. laddstart(strings, "1", "Ich");
    12. lforeach(strings, stringsForEach);
    13. system("PAUSE >NUL");
    14. return EXIT_SUCCESS;
    15. }
    16. void stringsForEach(char* key, char* data)
    17. {
    18. printf("%s: %s\n", key, data);
    19. }



    Jedoch sagt er mir jedes mal bei laddend, das current = nullptr ist. Jedoch verstehe ich das ganze nicht da ich doch einen zuvor mit malloc in linit einen Pointer als Rückgabewert erhalte?
    Oder übergibt es es als call-by-value? Das kann aber auch nicht sein da es eig. ein Pointer sein müsste

    C-Quellcode

    1. typedef struct node *List;


    Ich hoffe mir kann jemand helfen und auch die Logik dahinter erklären!

    Danke im vorraus!

    Grüße,
    DragonSlayerMarc
    There are only 10 types of people in the world: Those who understand binary and those who don't.
    Anmerkungen

    - in einer Header-Datei sollten keine Definitionen auftauchen, nur Deklarationen
    - deine typedefs sind etwas wirr
    - Zeile 8-18 solltest du vermutlich zu typedef struct { ... } Node; kombinieren
    - vorzugsweise const char * verwenden, wenn der Inhalt nicht geändert wird
    - Rückgabewert von malloc ggf. prüfen
    - Bug in lremove, falls key nicht in Liste
    - Speicher sollte man stets freigeben


    Zu deiner Frage: Mach dir klar, was du wohin übergibst.
    Spoiler anzeigen
    Main, Zeile 12:
    Auch wenn es ein Pointer ist, du praktizierst hier call by value. Um das gewünschte Resultat zu erhalten, kannst du z.B. die Adresse deiner Variable übergeben:
    linit(&strings, "2", "heiße");
    und dann im "Header":

    C-Quellcode

    1. void linit(List *l, char* key, char* data) {
    2. List list = (List) malloc(sizeof(Node));
    3. listl->Previous = NULL;
    4. listl->Key = key;
    5. listl->Data = data;
    6. listl->Next = NULL;
    7. *l = list;
    8. }


    Möglich wäre auch, das ganze per Rückgabewert zu machen:
    List strings = linit(strings, "2", "heiße");

    C-Quellcode

    1. List linit(char* key, char* data) {
    2. List list = (List) malloc(sizeof(Node));
    3. listl->Previous = NULL;
    4. listl->Key = key;
    5. listl->Data = data;
    6. listl->Next = NULL;
    7. return list;
    8. }

    Habe dies nun geändert bekomme jedoch trotzdem eine lesezugriffsverletzung bei laddend, Visual Studio gibt mir leider nur eine Pointer Adresse als genauere Information an.
    There are only 10 types of people in the world: Those who understand binary and those who don't.