Thread Merkwürdiges Verhalten von "split()"
(20 answers)
Opened by hlubenow at 2017-07-29 19:59 2017-07-31T16:22:11 hlubenow Ich meinte: du hast eine struct List, die einen Pointer auf den Kopf enhält (ggf. auch auf den Tail). Diese Pointer sind bei einer leeren Liste NULL. Als ListNode hast du eine struct mit ListNode *next, *prev; und deinen Daten. Quote Kann dein "string" auch sein. Ok, aber Motivation verstanden. Allerdings würde ich es trotzdem nicht machen: ich würde bei "string" eine Stringklasse vermuten, also irgendwas, das Funktionen wie string_init, string_append etc. anbietet, aber nicht ein normaler char* ist. Dasselbe mit dem stringpointer. Wenn, dann nenne ihn eher stringview - und der soll wirklich non-const sein? Jedenfalls rate ich dir davon ab. Es verwirrt nur. Quote Aber es ist ja genau NICHT einheitlich. Wenn ich ein int in die Liste packe: Code: (dl
)
1 int i = 1234; Während das bei TYPE_STRING nicht so ist. Auch macht hier doch niemand irgendwas mit free. Das ist doch nur irgendein Pointer. Derjenige, der hier den int in die Liste tut, muss die Lebenszeit sicherstellen. Wiederum nicht so bei dem TYPE_STRING. Dieser wird ja kopiert und lebt solange, bis das clearList aufgerufen wird. Das finde ich inkonsistent. Achja, deine Funktion sollte auch nicht push heißen, sondern wahrscheinlich list_push oder so. In C muss man mit Namen ja immer aufpassen... Quote Nein. Normalerweise macht eine Funktion eine Sache und nicht mehrere. Die Split-Funktion geht die Lebenszeit des Strings überhaupt nichts an. Das ist meine größte Kritik: du hast eine Liste, die nicht nur Liste, sondern auch noch irgendwie "managed pointer" sein will und auch noch mehrere Typen (anhand eines enums) unterschiedlich behandeln will. Es ist grundsätzlich schlecht, mehrere unterschiedliche Dinge in derselben Klasse zu tun. Zurück zum Split: Eigentlich gibt es nur 2 sinnvolle Arten für split: 1. split_inplace: Das split findet inplace statt und ändert den String (macht alle Trenner zu '\0'). Dann muss man nur pointer in den String zurückgeben und überhaupt kein malloc machen. 2. split_copy: Ein split, das nicht inplace ist und Kopien der Strings zurückgibt. Dann sollte aber der Eingabeparameter ein const char* sein (überhaupt kommt const bei dir gar nicht vor). Quote Der Punkt war: warum linked lists? Nicht: warum eine dynamische Struktur! Daher geht deine Antwort völlig an meiner Frage vorbei. Ein Array (bzw. ein Pointer auf einen dynamischen, zusammenhängenden Speicherbereich) wäre doch im Normalfall sinnvoller und schneller. Quote Ganz und gar nicht! Aber man muss mit malloc/free höllisch aufpassen und sollte daher unbedingt Kommentieren, wie sich Funktionen verhalten. Vor allem aber: keine Überraschungen wie "split freet eingabestring". Die Funktion heißt ja split und nicht split_and_free. Ansonsten können wir z.B. in https://www.c-plusplus.net/forum/f10 weiterdiskutieren, da das ja wenig mit Perl zu tun hat (Achtung: rauer Ton dort) - alternativ im C-Bereich hier (wo aber wohl weniger C-Leute sind). Einen Link auf eine Bibliothek hast du ja schon bekommen. Wie gesagt, bin kein C-Experte, kenne mich nur mit C++ aus. Da gibt es ein split in Boost und auch sogar ein split_regex, da geht bei Perl-Freunden gleich die Sonne auf :-) (In C gibt es bestimmt auch was passendes) Ich entwickle mit C++ schnell, mit C müsste ich mich mit viel zu viel low-level-Kram rumärgern. Aber naja, nicht jeder findet C++ besser als C - kommt sicher auch auf den Einsatzzweck an. Es gab insbesondere mit dem C++11-Standard einen riesengroßen Sprung, was die Einfachheit angeht (auto, for-Range-Schleifen, unique_ptr etc). Last edited: 2017-08-01 20:12:09 +0200 (CEST) |