Dynamisches Array von Pointern/Adressen in einem struct



  • Hallo,

    mein erster Beitrag gleich mit einem Problem das ich nicht nachvollziehen kann.

    Ich schreibe an einem XML zu json-Konverter und möchte in einem Struct, der Code mit Aufbau folgt, in einem Tag - Kinder-Tags mit Speicheradressen, als ein Array von Pointern/Adressen, verknüpfen.

    Aktuell erhalte ich aber "abstruse" Werte der Speicheradressen für manche Kind-Elemente. Andere stimmen mit den Adressen, ermittelt über Integer Indexe innerhalb einer TagList(e) überein.

    Bevor ich auf das Projekt mit Code auf Github verweise zu Referenz, folgend einige Snippets die das Problem einkreisen sollen.

    Gegeben ist folgendes struct "Tag":

    typedef struct tag {
        bool isClosed;
        bool isDataTag;
    
        unsigned int tabIndex;
        unsigned int entrieSize; // Anzahl der Kind Elemente
        unsigned int keyValueLength;
    
        char* name;
        char* tagData;
    
        struct keyValue* keyValues;
    
        // Zeiger auf das Elternelement (vom Typ Tag), funktioniert
        struct tag* parent;
    
        // unsigned Integer Indexe auf Elemente in der TagList
        unsigned int* children; 
    
        // Die problematische Pointer Deklaration,
        // soll sein, ein Array von Pointern/Adressen auf andere Tags
        struct tag** childrenPointer;
    
    } tag;
    

    Die TagList Deklaration:

    tag* tagList;
    

    Der Code der ein Kind Element hinzufügen soll, einmal als Pointer, die zweite Variante als Integer Index:

    TagCount entspricht im Code immer der Anzahl der Elemente in der TagList(e).

    // Add child tag**
    tagList[tagCount].parent->childrenPointer = (tag**) realloc(tagList[tagCount].parent->childrenPointer, sizeof (tag**) * (tagList[tagCount].parent->entrieSize + 1));
    tagList[tagCount].parent->childrenPointer[tagList[tagCount].parent->entrieSize] = &tagList[tagCount];
    
    // Add child tag indexes
    tagList[tagCount].parent->children = (unsigned int*) realloc(tagList[tagCount].parent->children, sizeof (unsigned int) * (tagList[tagCount].parent->entrieSize + 1));
    tagList[tagCount].parent->children[tagList[tagCount].parent->entrieSize] = tagCount;
    
    ++tagList[tagCount].parent->entrieSize;
    

    Folgend die Ausgabe der Adresse (zum debuggen):

    if (tagList[i].entrieSize != 0) {
        printf("Children\n");
        for (int j = 0; j < tagList[i].entrieSize; j++) {
            printf("%p address pointer - %p address index - %s\n", tagList[i].childrenPointer[j]->name, tagList[tagList[i].children[j]].name, tagList[tagList[i].children[j]].name);
            //printf("%s\n", tagList[i].children[j]->name);
        }
        printf("\n");
    }
    

    Über die Ausgabe habe ich auch den Fehler entdeckt, das sieht wie folgt aus:
    (Wichtig hierbei sind die markanten Unterschiede der "Address pointer" Adresse zu den "Address (by) Index"-Adresse.)

    Zum Beispiel Adressen von zwei Kind-Elementen (Children) mit dem gleichen Namen "listitem".

    Children
    0x182cdb0 address pointer - 0x182cdb0 address index - item
    0x2074757020646563 address pointer - 0x182db80 address index - item
    

    Hier auch eine, leicht gekürzte, Ausgabe mit XML Testdaten:

    jan@debian:~/Schreibtisch/starlight$ ./starlight2 -istandard_small.xml -v
    Source: standard_small.xml
    Showing output...
    Default output file used: "output.json"
    
    Print out summary:
    site - 0 index, 0 keyValues, 1 entries
    
    Children
    0x182cde0 address pointer - 0x182cde0 address index - regions
    
    regions - 1 index, 0 keyValues, 1 entries
    
    Children
    0x182cd50 address pointer - 0x182cd50 address index - africa
    
    africa - 2 index, 0 keyValues, 2 entries
    
    Children
    0x182cdb0 address pointer - 0x182cdb0 address index - item
    0x2074757020646563 address pointer - 0x182db80 address index - item // Warum steht hier diese falsche Adresse?
    
    item - 3 index, 1 keyValues, 12 entries
    KV: id : item0
    
    Children
    0x182d510 address pointer - 0x182ce40 address index - location
    0x64726f7779656b address pointer - 0x182cec0 address index - quantity
    0x7f080000000c address pointer - 0x182cf00 address index - name
    0x61206e6f6974636e address pointer - 0x182d200 address index - payment
    0x6f67657461636e69 address pointer - 0x182cff0 address index - description
    0x7470697263736564 address pointer - 0x182d360 address index - shipping
    0x30 address pointer - 0x182d400 address index - incategory
    0x182d460 address pointer - 0x182d460 address index - incategory
    0x664f2063 address pointer - 0x182d4e0 address index - incategory
    0x182db60 address pointer - 0x182db60 address index - incategory
    0x182d380 address pointer - 0x182d380 address index - incategory
    0x182ee60 address pointer - 0x182d690 address index - mailbox
    
    location - 4 index, 0 keyValues, 0 entries
    Data: United States
    
    quantity - 4 index, 0 keyValues, 0 entries
    Data: 1
    
    name - 4 index, 0 keyValues, 0 entries
    Data: duteous nine eighteen 
    
    payment - 4 index, 0 keyValues, 0 entries
    Data: Creditcard
    
    description - 4 index, 0 keyValues, 1 entries
    
    Children
    0x79726f6765746163 address pointer - 0x182d010 address index - parlist
    
    parlist - 5 index, 0 keyValues, 2 entries
    
    Children
    0x6f67657461636e69 address pointer - 0x182d070 address index - listitem
    0x182d1e0 address pointer - 0x182d1e0 address index - listitem
    
    listitem - 6 index, 0 keyValues, 1 entries
    
    Children
    0x79726f6765746163 address pointer - 0x182cd30 address index - text
    
    text - 7 index, 0 keyValues, 1 entries
    Data: page rous lady idle [...] smocks yielded 
    
    Children
    0x182d140 address pointer - 0x182d140 address index - keyword
    
    keyword - 8 index, 0 keyValues, 0 entries
    Data: officer embrace such fears distinction attires 
    
    listitem - 6 index, 0 keyValues, 1 entries
    
    Children
    0x756f697463616620 address pointer - 0x182d250 address index - text
    
    text - 7 index, 0 keyValues, 0 entries
    Data: shepherd noble supposed dotage humble servilius bitch theirs venus dismal wounds gum merely raise red breaks earth god folds closet captain dying reek  
    
    shipping - 4 index, 0 keyValues, 0 entries
    Data: Will ship internationally, See description for charges
    
    incategory - 4 index, 1 keyValues, 0 entries
    KV: category : category540
    
    [...]
    
    incategory - 4 index, 1 keyValues, 0 entries
    KV: category : category12
    
    mailbox - 4 index, 0 keyValues, 1 entries
    
    Children
    0x182d720 address pointer - 0x182d720 address index - mail
    
    mail - 5 index, 0 keyValues, 4 entries
    
    Children
    0x182d780 address pointer - 0x182d780 address index - from
    0x182d7e0 address pointer - 0x182d7e0 address index - to
    0x182d830 address pointer - 0x182d830 address index - date
    0x79726f7463697620 address pointer - 0x182d870 address index - text
    
    from - 6 index, 0 keyValues, 0 entries
    Data: Libero Rive mailto:Rive@hitachi.com
    
    to - 6 index, 0 keyValues, 0 entries
    Data: Benedikte Glew mailto:Glew@sds.no
    
    date - 6 index, 0 keyValues, 0 entries
    Data: 08/05/1999
    
    text - 6 index, 0 keyValues, 2 entries
    Data: virgin preventions half [...] ruffian life hamlet containing leaves  
    
    Children
    0x6f7661207375696c address pointer - 0x182d7a0 address index - keyword
    0x79726f6765746163 address pointer - 0x182da70 address index - emph
    
    keyword - 7 index, 0 keyValues, 0 entries
    Data: girdles deserts flood george nobility reprieve 
    
    emph - 7 index, 0 keyValues, 0 entries
    Data: armed 
    
    item - 3 index, 1 keyValues, 16 entries
    KV: id : item1
    
    Children
    0x726564726f20646e address pointer - 0x182d8e0 address index - location
    0x622068636e656220 address pointer - 0x182daf0 address index - quantity
    0x72756f6373696420 address pointer - 0x182db30 address index - name
    0x2073746e656d7572 address pointer - 0x182d9d0 address index - payment
    0x73756f6972756320 address pointer - 0x182da20 address index - description
    0x7020737365637865 address pointer - 0x182dec0 address index - shipping
    0x182fe30 address pointer - 0x182df90 address index - incategory
    0x206572 address pointer - 0x182dff0 address index - incategory
    0x182e0c0 address pointer - 0x182e0c0 address index - incategory
    0x182e140 address pointer - 0x182e140 address index - incategory
    0x182e220 address pointer - 0x182e220 address index - incategory
    0x182e2a0 address pointer - 0x182e2a0 address index - incategory
    0x182f030 address pointer - 0x182f030 address index - incategory
    0x182d900 address pointer - 0x182d900 address index - incategory
    0x182e600 address pointer - 0x182e600 address index - incategory
    0x182e680 address pointer - 0x182e680 address index - mailbox
    
    location - 4 index, 0 keyValues, 0 entries
    Data: Moldova, Republic Of
    
    quantity - 4 index, 0 keyValues, 0 entries
    Data: 1
    
    name - 4 index, 0 keyValues, 0 entries
    Data: condemn 
    
    payment - 4 index, 0 keyValues, 0 entries
    Data: Money order, Creditcard, Cash
    
    description - 4 index, 0 keyValues, 1 entries
    
    Children
    0x6877206369666661 address pointer - 0x182da40 address index - text
    
    text - 5 index, 0 keyValues, 0 entries
    Data: gold promotions [...] preparation  
    
    shipping - 4 index, 0 keyValues, 0 entries
    Data: Will ship only within country, Buyer pays fixed shipping charges, See description for charges
    
    [...]
    
    mailbox - 4 index, 0 keyValues, 1 entries
    
    Children
    0x182e730 address pointer - 0x182e730 address index - mail
    
    mail - 5 index, 0 keyValues, 4 entries
    
    Children
    0x182e790 address pointer - 0x182e790 address index - from
    0x182e820 address pointer - 0x182e820 address index - to
    0x182e870 address pointer - 0x182e870 address index - date
    0x182e8b0 address pointer - 0x182e8b0 address index - text
    
    from - 6 index, 0 keyValues, 0 entries
    Data: Javam Suwanda mailto:Suwanda@gmu.edu
    
    to - 6 index, 0 keyValues, 0 entries
    Data: Mehrdad Glew mailto:Glew@cohera.com
    
    date - 6 index, 0 keyValues, 0 entries
    Data: 11/28/1999
    
    text - 6 index, 0 keyValues, 5 entries
    Data: back greg [...] slew  
    
    Children
    0x182e7b0 address pointer - 0x182e7b0 address index - keyword
    0x182ebe0 address pointer - 0x182ebe0 address index - keyword
    0x182e160 address pointer - 0x182e160 address index - bold
    0x182e180 address pointer - 0x182e180 address index - emph
    0x182e1a0 address pointer - 0x182e1a0 address index - keyword
    
    keyword - 7 index, 0 keyValues, 0 entries
    [...]
    
    keyword - 7 index, 0 keyValues, 0 entries
    Data: season presently victory women beating
    

    Falls jemand den Code genauer unter die Lupe nehmen will, folgend auch ein Link auf das Github Projekt:
    https://github.com/jrie/starlight

    Die Code Ausschnitte sind aus "starlight2.c", die Ausgabe ist aus der Standard_small.xml mit folgender Parameterübergabe:
    "starlight2(.exe) -istandard_small.xml -v"

    Ist leider etwas sehr umfangreich aber ich wüsste nicht wie ich das Problem kürzen könnte, ich bitte um Verständnis und hoffe das mir hier jemand auf den richtigen Sprung helfen kann.



  • Der Code ist eine Zumutung.
    Globale Variablen und von Funktionen hast du auch noch nichts gehört.
    Schreibe den Code einmal neu aber vernünftig, dann hast du mit nur noch 1/3 des Umfanges auch einen besseren Überblick um deinen Fehler zu finden.



  • da es schon an andere Stelle Kritik für meine zugehagelte Main gegeben hat, habe ich an dieser Stelle vier Funktionen erstellt die den Code etwas entschlackt haben und 2 Identation Levels weggebrochen, ohne neue Fehler einzubauen. Soweit ich das konnte.

    Ich bin mir zum Teil noch unsicher in C und habe bei weitem noch nicht alle Fallstricke verinnerlicht, daher möge man mir für meinen Code, der mit Sicherheit nicht peferkt ist, verzeichen.
    Ich lerne noch, halte mich aber für Lernwillig, wenn nicht immer gleich direkt fähig dazu.

    Die globalen Variablen habe ich bis auf drei reduziert und static gesetzt.

    Das weitere Problem zur Code-Optimierung, ich weiß nicht in wie weit ich die switch/case statements herunterbrechen soll, was soweit für mich ersichtlich ist habe nun bereits auf Github wieder online gestellt. Also zumindest die wirklich repeating parts in Funktionen eingebettet.

    Unter anderem auch das Problemkind welches mir hier das Leben schwer macht befindet sich nun in der "CreateTag" Funktion, anstelle zwei mal im Code verstreut.

    Wenn sich also doch jemand erbarmen kann einem Hobby-Entwickler etwas unter die armen Zugreifen der sein Lohn und Brot nicht mit Softwareentwicklung direkt verdient, aber dazu lernen möchte. 🕶

    Ansonsten tuts mir halt wirklich leid wenn der Code nicht gerade augenschmeichelnd daherkommt.



  • Ohne mir das Alles anzusehen - wenn du allen angeforderten Speicher auch wieder korrekt frei gibst, fresse ich einen Besen. Traue ich dir nicht zu.



  • Hallo EOP,

    ich teste den Code mit Valkyrie bzw. ist das ein Frontend für Valgrind/Memcheck unter Linux/Debian.

    Aller Speicher wurde korrekt freigegeben. Aber du meinst vermutlich das ständige Malloc, Realloc's ?

    Ich habe zum Großteil schon darauf geachtet und getestet das Speicher korrekt freigegeben wird, ob das bei dem Problem eine Rolle spielt, ich weiß es nicht.

    Aber so lange man der Aussage von Valgrind trauen darf, wird kein Byte geleaked oder ein Byte geschrieben das nicht reserviert wurde oder ein Byte gelesen das nicht geschrieben wurde.

    Wie es mit dem Pointer zu Pointern/Adressen aussieht, das habe ich nicht nachvollzogen.

    *Edit:
    In der Tat leaked der Code gerade ein paar Bytes, ich habe jetzt die Standard_small.xml als Standard in den Code gesetzt welche automatisch aufgerufen wird wenn kein Parameter übergeben wird.

    Das kam erst nach dem Refactoring. - bevor das Problem aufkam 😕



  • theSplit schrieb:

    In der Tat leaked der Code gerade ein paar Bytes

    Haha, bin ich wieder einmal drumrum gekommen einen Besen zu verspeisen. 😉



  • Wenn du mir nun auch sagst wo der Fehler liegt, darfst du auch auf dem Besen reiten 😉



  • theSplit schrieb:

    Wenn du mir nun auch sagst wo der Fehler liegt, darfst du auch auf dem Besen reiten 😉

    Siehe die erste Zeile von Wutz seiner Antwort.

    EDIT:
    Abgesehen davon bin ich schon auf so einigen Besen rumgeritten. 🙂

    EDIT #2:
    Dürfte höchstwahrscheinlich an ** liegen. Wieder ohne mir den ganzen code anzusehen. Aber mein Gefühl ist meistens ziemlich zuverlässig. (Ausser du hast was ganz grundsätzliches freizuugeben vergessen)



  • Wenn Wutz mir dann auch nochmal Feedback gibt was ich verbessern kann, mach ich das gern. 🙂

    @EOP
    Ich glaube ich komm in einen Hexenkessel wenn ich hier weitere herumstachele 😉



  • theSplit schrieb:

    Wenn Wutz mir dann auch nochmal Feedback gibt was ich verbessern kann, mach ich das gern. 🙂

    @EOP
    Ich glaube ich komm in einen Hexenkessel wenn ich hier weitere herumstachele 😉

    Nö, ich bin so ziemlich der einzige Schmutzfink hier. Die meisten Anderen sind "die Guten".


  • Mod

    Es wäre gut, wenn du uns deine überarbeitete Version zeigen würdest. Und zwar sowohl vollständig (so dass man sie einfach kopieren und ausführen kann) als auch auf das wesentliche Problem reduziert. Siehe:
    Wie man Probleme nachstellbar und nachvollziehbar macht
    Am besten mit einer Beispielausgabe und einer Beschreibung, welche Ausgabe eigentlich erwartet wäre.

    Fast 1000 Zeilen Code wird sich niemand einfach mal eben so durchlesen. Zumal es bereits jede Menge Verdächtige gibt, da du, wie von Wutz und EOP (auf ihre etwas eigenartige Weise) beschrieben, ein paar schwere Programmiersünden begehst. Die Anzahl globaler Variablen sollte 0 sein, nicht 1 und erst recht nicht 3 und ob sie static sind oder nicht ist wurscht. Ebenso hast du offensichtlich Schwächen bei der manuellen Speicherverwaltung, die du anscheinend viel zu großmütig einsetzt und zudem scheinst du jede Menge Mythen aus schlechten Lehrbüchern aufgeschnappt zu haben, wie diese komische NULL-Prüfung vor dem free oder die vielen Casts. Zudem ist der Code äußerst unübersichtlich und es ist schwer Fehler da drin zu finden. Normalerweise sollte eine Funktion bloß ein paar Zeilen lang sein, du hast alles in einer einzigen Funktion!

    All dies, globale Variablen, (schlecht umgesetzte) manuelle Speicherverwaltung, Pointergefrickel und unübersichtlicher Code sind bekannt als sehr häufige Fehlerquellen. Es wäre ein Wunder, wenn es nicht da dran läge. Aber eine Verbesserung der unmittelbaren Ursache wäre ziemlich müßig. Solange die eigentlichen Ursachen, nämlich die genannten Programmiersünden, nicht behoben werden, wird ein Finden und Verbessern des unmittelbaren Fehlers bloß dazu führen, dass der nächste Fehler sich an anderer Stelle äußern wird. Eine Komplettüberarbeitung nach gängigen Best-Practices wäre daher wohl die beste Vorgehensweise. Höchstwahrscheinlich löst sich das Problem dabei von ganz alleine.



  • Ich versuche was ich machen kann. Ob ich alles nach "Best practice" umschreiben kann weiß ich allerdings nicht. Da fehlt mir auch das Know-How zu, da ich mich mit den Gewohnheiten von gestandenen C-Codern nicht auseinandergesetzt habe.

    So fern es Kritik gibt die man umsetzen kann, vielleicht auch wirklich nur sehr problemspezifisch, bin ich gerne Willens diese Umzusetzen.

    Aber das setzt auch voraus das man jemanden der kein Guru ist auch etwas mit der Nase auf das Problem stößt - außerdem, ich bin Hobby-Programmierer - so sieht der Code vermutlich auch aus, da ich selbst nicht einschätzen kann wo und wie man am besten die Kanten ausbügelt.

    Ist auch mein letztes Feedback für heute. Ich wollte nur mal darauf hinweisen das man nicht als Meister in einem Thema beginnt.

    Und ja, ich habe mit den Büchern von Jürgen Wolf angefangen die Grundlagen von C zu lernen. Darüber gibt es aber auch anderorts hier Threads wie man es besser nicht machen sollte, war aber zu spät.

    Trotzdem würde ich den Code ungern in das Nirvana schicken, weil ich die Routine zum lesen und schreiben von Tags schon einmal - mit meinem Wissensstand überarbeitet hatte. Daher wäre ich ja auch sehr offen für problemspezifische Kritik.

    Das hat aber auch nur wenig mit dem Grundproblem zu tun, es gibt ein paar Versionen vor dem aktuellen Stand wo keine Speicherleaks aufgetreten sind, aber der Code hals "dirty" runtergeschrieben war. Um auf eine Rückmeldung einzugehen.



  • Weil ich mir auch fast 1000 Zeilen code durchlese wenn ich nicht wirklich was für meine Interessen und für mich Nützliches lernen kann. Da bin ich durchaus eigenartig (und die meisten Anderen wahrscheinlich auch).



  • Ich kann ja versuchen das ganze auf ein Beispiel herunterzubrechen, aber es wird nicht diesen Umfang besitzen noch diese Komplexität wie es aktuell der Fall ist.

    Und das ist halt das geforderte Spektrum der Aufgabenstellung, ob ich das in Funktionen schreibe oder nicht.

    Was wollt ihr denn lernen? Nur Quality Code mit neuen Algorithmen und wissenschaftlichen Durchbrüchen? - Macht eurem Frust doch besser wo anders Platz als in diesem Thread, ich bin weder Wissenschaftler noch beruflicher Programmierer.

    Macht mich sauer diese Grundeinstellung gegenüber jemand neuem hier im Forum...

    Oder muß ich ganz vorsichtig schreiben "C Anfänger, erbitte um Problembeantwortung" ?

    Wenn ich wüßte wo der Fehler liegt würde ich Ihn selbst beantworten, dann kann ich von mir aus auch ein Beispiel dem zugrunde Aufbauen.


  • Mod

    theSplit schrieb:

    Ich kann ja versuchen das ganze auf ein Beispiel herunterzubrechen, aber es wird nicht diesen Umfang besitzen noch diese Komplexität wie es aktuell der Fall ist.

    Das wäre das Beste und ist allgemein eine sehr gute Methode, einen Fehler zu finden. Niemand kann und will einen Fehler in 1000 Zeilen Code suchen, wenn 900 davon irrelevant sind. Wenn du beim Kürzen des Codes feststellst, dass der Fehler nicht mehr auftritt (dies ist nach jeder Kürzung zu prüfen!) dann liegt der Fehler höchstwahrscheinlich in dem gekürzten Teil und du wirst ihn sehr wahrscheinlich selber finden, wenn du dir anguckst, wieso der gekürzte Teil den Fehler verursacht. Deshalb habe ich dir den obigen Link gegeben, denn du bist schließlich nicht der erste, der mit einem extrem langen Programm ankommt und da drin einen bestimmten Fehler sucht. Es ist wichtig, zu lernen, wie man selber Fehler findet oder zumindest anderen die Fehlersuche erleichtert (denn das erleichtert sie einem auch selber).

    Und das ist halt das geforderte Spektrum der Aufgabenstellung, ob ich das in Funktionen schreibe oder nicht.

    Und? Du suchst doch eine Erklärung des Fehlers und nicht eine Lösung für die Aufgabenstellung, oder? Also reduzier den Code auf den Fehler!

    Was wollt ihr denn lernen? Nur Quality Code mit neuen Algorithmen und wissenschaftlichen Durchbrüchen? - Macht eurem Frust doch besser wo anders Platz als in diesem Thread, ich bin weder Wissenschaftler noch beruflicher Programmierer.

    Das sollte keine Ausrede sein, es nicht wenigstens zu versuchen. Wenn du sagst, dass du ruhig pfuschen darfst, weil du keine hohen Ansprüche an dich selber hast, ist es dann ein Wunder, wenn Pfusch heraus kommt? Es ist praktisch sicher, dass der Fehler in deinem Programmierstil begründet liegt. Wie sollen wir dir das sonst sagen, außer dass wir es dir eben sagen? Sollen wir so tun, als wäre das so in Ordnung? Das hilft dir doch auch nicht weiter.

    Macht mich sauer diese Grundeinstellung gegenüber jemand neuem hier im Forum...

    Verwechselte Direktheit nicht mit Grobheit! Wutz und EOP nehmen kein Blatt vor den Mund, wenn sie sagen, dass der Code eine Zumutung ist, dann weil er es ist. Wenn sie dich persönlich beleidigen wollten klänge das anders und jemand (das wäre wahrscheinlich ich) würde sie auch für solch eine Verfehlung zurecht weisen. Dies ist eine in Foren wie diese übliche Art der Kommunikation, wo es in erster Linie um das Lösen von Problemen geht und nicht darum dass der Fragesteller sich wohl oder geborgen fühlt.



  • Nicht mal ich hab bisher von SeppJ oder einem anderen mod oder admin eine Zurechtweisung einstecken müssen - und ich bin manchmal mehr als direkt.

    Es ärgert die Leute, die sich im Forum Mühe geben jemandem zu helfen wenn sie den Eindruck haben, daß du dir nicht selber Mühe gibst.

    Ist nichts persönliches.

    https://www.google.de/search?q=free+pointer+to+pointer+c



  • Okay, nach dieser Antwort bin ich auch wieder ein wenig besänftigt.

    Aber was ich dennoch nicht verstehe, ich kann von dem Parser wenig abstrahieren als ich schon, meines Wissenstandes nach, gemacht habe.

    Ich könnte ein paar mehr Comments setzen, das würde nicht den Code aufwerten, aber die Lesbarkeit erhöhen.

    Dennoch stehe ich vor diesem massigem switch/case / if else Fälle Konstrukt. Und da brauche ich halt Anleitungen was es besser zu machen gilt, das habe und kann ich mir nicht eben gerade weil es jemanden stört anlesen.

    Aber gut, ich arbeite an dem Code weiter und versuche auszulagern was geht, so sinnvoll es geht. Das mache ich aber auch nicht mehr heute. Es wird vielleicht mit dem richtigen Feedback kommen.

    Hier habe ich das leider bisher nicht gesehen, auch wenn ich verstehen kann das man nicht auf alles, aber zumindest auf einen Teil eingehen kann.

    Ich frage mich gerade warum ich ausfaktoriert habe, falsch meiner Annahme nach, um dann Fehler einzubringen, nur das sich niemand über die Main beschwert.

    Ein schweres Los.

    Ich arbeite weiter an dem Code und hoffe das ich Feedback bekomme um das zu Optimieren was alles beastandet hatten, bzw. ein Teil dessen.

    Dann kann ich mich auch um das kümmern was Sinn der Frage war, das Problem zu lösen.



  • Eine Sache will ich noch anmerken:
    Prüfung auf NULL vor free ergibt schon Sinn - aber nur, wenn man sich den Check in free sparen will und damit überhaupt den Overhead beim Aufruf. Der ist marginal - kann aber trotzdem relativ schnell aufsummieren. Ein Check ohne Aufruf geht meistens schneller als ein Aufruf und dann Check.

    Vernichtet aber so ein bisschen die Lesbarkeit, wenn man das überall durchsetzt. Ein kleines Makro kann hier helfen, sowohl Lesbarkeit zu erhöhen als auch den Overhead des Calls zu sparen.


  • Mod

    Hier sieht mir das aber doch stark so aus, als könnten die Zeiger überhaupt nie NULL sein. Cargo Cult.



  • Wohl wahr. Aber einem Anfänger/Hobbyentwickler generell "Auf NULL prüfen vor free ist blöd" zu sagen ist doof, weil wir doch halt Gewohnheitstiere sind - auch bei schlechten Angewohnheiten. Und dann machen wir Sachen blind, ohne uns darüber zu wundern, warum wir sie so machen. Man sollte zumindest schon mal davon gehört haben - und irgendwann, wenn die Cycles dann zählen, erinnert man sich daran, dass es da diesen Sonderfall gab, mit dem man noch ein bisschen Geschwindigkeit herrauspressen kann ...

    Genauso verkettete Listen. Sind generell blöde, aber dann gibt es tatsächlich Anwendungsfälle, wo sie das Mittel der Wahl sind. Und wenn man vorher "verkettete Listen sind doof" sagt, dann raubt man einem Anfänger auch die Möglichkeiten, wo VLs halt die beste Performance liefern.

    War halt allgemein gesprochen, nicht unbedingt im direkten Bezug zum geposteten Code. Sondern nur als Notiz, damit der OP weißt, dass es Anwendungsfälle gibt, wo dies schon seinen Sinn ergibt.

    EDIT: "war" zu "wahr" - ich sollte nicht mehr völlig übermüdet Posts schreiben ...


Log in to reply