structs kopieren
-
Hey,
ich will ein Programm bauen, dass alle TCP-Services auf einem Linux System ausliest und in einem Vector speichert (später soll mal effizient verwaltet werden, aber alles zu seiner Zeit).
Dafür gibt es die Funktion getservent(), die bei jedem Aufruf einen Zeiger auf das nächste struct servent zurück gibt.Diese servents sehen so aus:
struct servent { char *s_name; /* official service name */ char **s_aliases; /* alias list */ int s_port; /* port number */ char *s_proto; /* protocol to use */ }Ihr seht, dass es dort cString gibt. Außerdem gibt die Funktion getservent innerhalb eines Programmaufrufs IMMER die gleiche Speicheradresse zurück, das heißt, dass das alte servent im Speicher einfach überschrieben wird.
Ich will aber gern alle servents in meinem Programm zur Verfügung haben. Also würde ich gern eine tiefe kopie der structs machen.Gibt's dafür einen schönen Weg? Bzw. habe ich versucht, die Werte einzeln zu kopieren - aber bei
struct servent *serv, myserv; while( (serv = getservent()) != NULL ) { myserv.s_name = (char*) malloc( strlen(serv->s_name) ); strcpy(myserv.s_name, serv->s_name); }gibt es irgendwann (nicht sofort, ich kann mit ziemlich viele der kopierten Namen ausgeben lassen) ein "malloc(): memory corruption" - falls mir das jemand erklären kann, auch bitte her damit! Zuviele malloc?! Aber ich krieg keinen NULL-Pointer zurück...
Die wichtige Frage aber: Wie kopiere ich diese structs, damit ich in meinem Programm mit ihnen arbeiten kann?
Viele liebe Grüße!
gibt's
-
Die beste Lösung wäre es vermutlich, den struct um einen Copy-Ctor und Zuweisungsoperator zu erweitern, der sich um das Kopieren des Speichers kümmert.
wenn du die Klasse selbst nicht beeinflussen kannst, leite eine eigene Klasse davon ab:
class my_servent : public servent { void copy(const servent& src);//hier kommen die malloc/strcpy-Aufrufe rein public: my_servent(const my_servent& other) {copy(other);} my_servent(const servent& src) {copy(src);} //analog auch op= ~my_servent();//alle angelegten Speicherbereiche free()en };Zu dem Speicherfehler: Du hast nicht zu oft malloc() aufgerufen, sondern jeweils zu wenig Speicher angefordert. Ein c-String benötigt
strlen(str)+1Bytes Speicherplatz (das letzte für die abschließende \0), so daß du über das Ende des reservierten Platzes hinausschreibst. Und offenbar hast du bei einer der Kopier-Operationen die Steuerdaten von malloc() zerlegt.
-
Vielen Dank für die schnelle Antwort,
was das Vorgehen des Kopierens angeht, werde ich mir eh ein paar Methoden schreiben, weil ich auch noch char** zu kopieren habe.
Was den Speicherfehler angeht, versinke ich jetzt ganz schnell im Boden und versuche irgendwie glaubhaft zu versichern, dass es bestimmt nur einfach viel zu früh ist und ich das schon hundert mal gemacht habe und jedes mal die +1 dran hatte und nur heute...ein schlechter Tag für cString ist! *g*
Danke nochmal.
-
@Chew
Die erste Frage ist immer C oder C++ ?
Die zweite dann, in welcher form brauchst du die infos ueber das Event, muessen die als servent structuren vorliegen (weiterverarbeitung) oder isses egal ....
Bei C musst ziemlich alles haendisch machen ....
also speicher fuer strings allocieren, strings kopieren, zeiger in die struct packen ... zeiger auf die strukts selber in arrays oder verkettete listen verwalten .... nicht ganz untrivial in c
Ciao ...
-
Hallo RHBaum,
hehe - tja, ob C oder C++ ist nicht ganz so einfach. Nun, ich mache schon C++, ich komme aber um C nicht herum, weil getservent() nunmal von nur C-Konstrukte, inklusive der cString verwendet.
Ansonsten wäre es gut, wenn ich am Ende wirklich servent Strukturen hätte. Ich bau gerade eine Klasse, die das bewerkstelligt.
Was die Speicherverwaltung angeht, ist mir das alles wirklich nicht fremd. Ich weiß gut, wie haarig das ist. Die Sache mit dem \0 war jetzt wirklich ein doofer Fehler, aber der passiert einem wohl immer wieder mal. Eigentlich krieg ich das mit etwas Konzentration aber hin.
Viele Grüße!