(Erledigt) Array dynamik (ohne vektor)



  • Hallo erstmal,

    edit:: Problem gelöst, siehe http://www.c-plusplus.net/forum/viewtopic-var-p-is-1692735.html#1692735

    ich bin noch ne in diesem Forum, und bin auch noch ein Anfänger (wenn nicht sogar blutiger Anfänger) in c++ (Befasse mich normalerweise eher mit webprogrammierung)

    Ich habe vor kurzem mit der Ausbildung zum Fachinformatiker für Anwendungsentwicklung angefangen und habe eine Aufgabe bekommen,

    ich hatte im vorfeld eine doppelt verkettete liste erstellt die auch ihren dienst tut, und soll jetzt eine Baumstrucktur daraus machen, folglich aus nur einem Unterelement sollen unbegrenzt viele neue werden.

    Rahmenbedigung:

    Ich soll dies mithilfe eines Statischen Arrays machen.(ohne Vektor)

    struct TListenKnoten
    	{
    		string nodename;
    		string wert;
    		TListenKnoten *lastelement;
    		TListenKnoten **Sarray;
    
    	};
    
    	struct TListenKnoten *handle=0;
    	struct TListenKnoten *startknoten=0;
    	struct TListenKnoten *neu=0;
    	int count;
    	string auswahl="0";
    

    Das ist erstmal das struckturelement an sich und die dazugehörigen globalen variablen.
    mein ansatz ist, das ich im TListenKnoten einen Pointer habe der auf ein array aus pointern zeigt die wiederrum auf die folgenden structurelemente zeigen.

    der array soll nach aufgabenstellung (ich würds ja anders machen...) beim erstellen eines neuen subelements in einen anderen array rüberkopiert werden und im anschluss ein neuer array erstellt werden der ein feld größer ist, und dann natürlich zurückkopieren.

    Hier de Quelltext bezüglich des Kopierens der Arrays

    TListenKnoten *arbackup[sizeof(handle->Sarray)/sizeof(handle->Sarray[0])];
    			count=0;			
    			while (handle->Sarray[count]!=NULL)
    			{
    				arbackup[count]=handle->Sarray[count];
    				count++;
    			}
    
    			delete handle->Sarray;
    
    			handle->Sarray=new struct TListenKnoten*[sizeof(arbackup)/sizeof(arbackup[0])+1];
    			count=0;
    			while (count<(sizeof(arbackup)/sizeof(arbackup[0])))
    			{
    				handle->Sarray[count]=arbackup[count];
    				count++;
    			}
    

    die Aktuelle Problematik ist, das scheinbar irgendetwas beim Kopieren der Arrays nicht richtig funktioniert, bzw. der Array nicht wie gewünscht vergrößert wird.
    Bei der Ausgabe zeigt er lediglich das zuletzt erstellte element.
    Mein erster verdacht war, dass er das erste element überspeichert, allerdings zeigt er mir beim testen, das dieses element des arrays leer ist.

    hat jemand ne idee bzw. nen rat für mich?

    und btw. ich weiß, globale variablen nur setzen wenn man einen guten grund hat^^ ich habs hier einafch mal gemacht um formfehler zu vermeiden, erstmal solls funktionieren, dann wirds schön gemacht.

    Ich bedanke mich jetzt schonmal für jede hilfestellung

    Grüße Lodoss

    PS: Hier nochmal der gesamte Quelltext:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    	struct TListenKnoten
    	{
    		string nodename;
    		string wert;
    		TListenKnoten *lastelement;
    		TListenKnoten **Sarray;
    
    	};
    
    	struct TListenKnoten *handle=0;
    	struct TListenKnoten *startknoten=0;
    	struct TListenKnoten *neu=0;
    	int count;
    	string auswahl="0";
    	int durchlauf=0;
    
    int main ( int argc, char *argv[] )
    {
    
    	do
    	{
    		cout << "[## Menü ##]" << endl;
    		cout << "[n] Neuen Knoten erstellen" << endl;
    		cout << "[l] Liste" << endl;
    		cout << "[q] Ende" << endl;
    
    		count=0;
    		if (handle!=0) {
    			while (handle->Sarray[count]!=NULL)
    			{
    				cout << "[" << count << "]" << handle->Sarray[count]->nodename << " ";
    				count++;
    			}
    		}
    		cout << endl;
    
    		cin >> auswahl;
    
    		if (auswahl=="n") 
    		{
    			if (startknoten==0)
    			{
    				neu = new struct TListenKnoten;
    				startknoten=neu;
    				handle=startknoten;
    			}
    			else
    			{
    				neu = new struct TListenKnoten;
    			}
    
    			neu->Sarray = new struct TListenKnoten*[0];
    			cout << "Name des Knotens:" << endl;
    			cin >> neu->nodename;
    			cout << "Wert des Knotens: " << endl;
    			cin >> neu->wert;
    
    			count=0;
    
    			while (handle->Sarray[count]!=NULL)
    			{
    				count++;
    			}
    
    			// Kommentar: Array Vergrößern
    
    			TListenKnoten *arbackup[sizeof(handle->Sarray)/sizeof(handle->Sarray[0])];
    			count=0;			
    			while (handle->Sarray[count]!=NULL)
    			{
    				arbackup[count]=handle->Sarray[count];
    				count++;
    			}
    
    			delete handle->Sarray;
    
    			handle->Sarray=new struct TListenKnoten*[sizeof(arbackup)/sizeof(arbackup[0])+1];
    			count=0;
    			while (count<(sizeof(arbackup)/sizeof(arbackup[0])))
    			{
    				handle->Sarray[count]=arbackup[count];
    				count++;
    			}
    			cout << "count ist: " << count << endl;
    
    			handle->Sarray[sizeof(handle->Sarray)/sizeof(handle->Sarray[0])-1]=neu;
    		}
    
    		if (auswahl=="l")
    		{
    			//rekursive schleife aller elemente => funktion
    
    			/*
    			funktion X
    			{
    				for ("anzahl subelemente vom derzeitigen hangeln")
    				{
    					cout name des subelements
    					aufruf von "funktion X" mit hangeln auf subelement
    
    				}
    			}
    			*/
    		}
    
    	}
    	while (auswahl!="q");
    
    	return 0;
    }
    


  • std::vector



  • kurz&knapp schrieb:

    std::vector

    jop, wäre auch mein ansatz, es geht bei der aufgabe aber primär darum, die Baumstruktur zu verdeutlichen, ich würds auch gerne mit nem vektor machen, allerdings ist die aufgabenstellung explezit: "statischer array"

    PS: wirklich kurz und knapp die antwort^^

    PS: ich habe natürlich auch schon die boardsuche ausgeschöpft, das inetrnet durchstöbert und tutorials durchgeschaut, entweder nix egfunden oder eben "benutz nen vektor" (was ja richtig ist, nur in meinem falle nicht umsetzbar)



  • Ich soll dies mithilfe eines Statischen Arrays machen.(ohne Vektor)

    deine arrays sind aber nicht statisch.

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?



  • kurz&knapp schrieb:

    Ich soll dies mithilfe eines Statischen Arrays machen.(ohne Vektor)

    deine arrays sind aber nicht statisch.

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?

    streng genommen sind es nicht mal arrays...



  • kurz&knapp schrieb:

    Ich soll dies mithilfe eines Statischen Arrays machen.(ohne Vektor)

    deine arrays sind aber nicht statisch.

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?

    nunja, beibringen ist das eine, verständnis das andere 😉
    es geht primär ums verstnis der struckturen und deren funktionsweise, die man sonst so leichtfertig benutzt

    streng genommen sind es nicht mal arrays...

    inwiefern, was unterscheidet mein "konstruckt" von dem ich denke das es ein array ist von einem array? ist ne reine neugierfrage am rande, sollte aber nicht zu weit vom thema wegführen

    derweil habe ich auch noch weiter versucht das problem zu lösen und mir mal
    (sizeof(handle->Sarray)/sizeof(handle->Sarray[0])
    ausgeben lassen, der zurückgegebene wert ist immer 1, daher vermute ich den fehler hier:

    handle->Sarray=new struct TListenKnoten*[(sizeof(arbackup)/sizeof(arbackup[0]))+1];
    

    sodass der neue array nicht größer als der alte ist, und damit nicht über das erste folgeelement hinausgeht

    allerdings ist dies nur eine vermutung



  • Lodoss schrieb:

    es geht primär ums verstnis der struckturen und deren funktionsweise, die man sonst so leichtfertig benutzt

    wenn es um strukturen verstehe ich erst recht nicht, warum vector nicht benutzt werden darf...

    derweil habe ich auch noch weiter versucht das problem zu lösen und mir mal
    (sizeof(handle->Sarray)/sizeof(handle->Sarray[0])
    ausgeben lassen, der zurückgegebene wert ist immer 1

    das ist nicht weiter verwunderlich, weil du die größe eines zeigers auf einen zeiger durch die größe eines zeigers teilst.
    wenn du in den ausdruck mal die konkreten typen reinschreibst, wird es vielleicht klar:
    sizeof(TListenKnoten**)/sizeof(TListenKnoten*)
    ein TListenKnoten** ist genau so groß wie ein TListenKnoten*, deshalb kommt da immer 1 raus.

    ein statisches array sieht übrigens so aus:

    int array[100]; // größe muss eine konstante sein
    

    new hat da nix verloren.



  • zuallererst, vielen dank für eure antworten, vorallem Kurz&Knapp, dass ist eine plausible erklärung für dieses mir unerklärliche verhalten des programms, ich lass nochmal von mir hören wenn ich das problem gelöst habe. (keine sorge, keine frage, sondern meine problemlösung, damit die selbe frage nicht nochmal gestellt werden muss [wie so oft])

    was die arays betrifft, nach meinem verständnis ist also ein statisches array ein array, dessen größe konstant ist und von programmstart an klar ist, ein dynamisches array ein array dessen größe sich zur laufzeit ergibt und ein vector ist ein "array" dessen größe sich wärend der laufzeit ändern kann, liege ich damit richtig?
    (euer wissen und eure zeit soll ja nicht verschwendet sein)



  • Lodoss schrieb:

    was die arays betrifft, nach meinem verständnis ist also ein statisches array ein array, dessen größe konstant ist und von programmstart an klar ist, ein dynamisches array ein array dessen größe sich zur laufzeit ergibt und ein vector ist ein "array" dessen größe sich wärend der laufzeit ändern kann, liege ich damit richtig?

    Ja, damit liegst du richtig. Wobei std::vector eine gesamte Klasse ist, die noch viel mehr Funktionalität bietet. Aber das hast du wahrscheinlich mit den Anführungszeichen gemeint.

    kurz&knapp schrieb:

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?

    Weil sie gewisse Dinge nicht lernen, wenn sie von Anfang an nur STL benutzen. Was eher vorkommt, ist die Tatsache, dass sie danach nicht mal zu solchen Dingen greifen und für Programme, die effizient sein sollen, dauernd Low-Level-Dinge anwenden. Und viele Leute haben auf diese Weise trotzdem das Gefühl, einen Grossteil von C++ verstanden zu haben...



  • kurz&knapp schrieb:

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?

    Ich fidne es zu trainingszwecken nicht verkehrt wenn die leute wissen wie es innen drin aussieht und in die lage kommen sowas auch selbst mal zu schreiben.



  • Xebov schrieb:

    kurz&knapp schrieb:

    warum bringt man leuten eigentlich c++ bei, wenn sie es nicht benutzen dürfen?

    Ich fidne es zu trainingszwecken nicht verkehrt wenn die leute wissen wie es innen drin aussieht und in die lage kommen sowas auch selbst mal zu schreiben.

    Naja. Was hast du denn an Einblick gewonnen, wenn du

    int* a = new int[23];
    

    schreibst anstelle von

    std::vector<int> a(23);
    

    ?



  • Vector besteht aber schon aus ein bischen mehr als nem Konstruktoraufruf.



  • Das schon. Aber was gewinnt man dadurch, wenn man willkürlich einen Teil des Ganzen ausblendet und nur noch das betrachtet was übrig bleibt?

    Wenn man lernen soll mit Zeigern und Allokationen umzugehen, warum wird dann nicht C gelehrt statt so ein kleines Subset von C++? Es ist doch völlig realitätsfern, in C++ mit new und raw arrays zu hantieren. Das tun doch nur die, die es (noch) nicht verstanden haben. Oder denen man es halt so beigebracht hat und nun glauben, sie kennen C++, obwohl sie nicht mal an der Oberfläche gekratzt haben.



  • Naja aber sie es mal von der rein Inhaltlichen und übungsmäßigen Seite. Du sagst OK schreibt ne Vector-Klasse mit allem drum und dran, dann zeigste den Leuten das es genau diese klasse schon über std gibt und das sie die dann auch benutzen sollen. Das selbst schreiben so einer Klasse zeigt den leuten imerhin wie sie im ganzen Funktioniert und ist meiner Meinung nach für Anfänger durchaus ne gute Übung.



  • TListenKnoten *arbackup[sizeof(handle->Sarray)/sizeof(handle->Sarray[0])];
    

    Da Sarray in deinem Beispiel ein Zeiger ist, ist das da oben totaler Unfug.



  • was die arays betrifft, nach meinem verständnis ist also ein statisches array ein array, dessen größe konstant ist und von programmstart an klar ist, ein dynamisches array ein array dessen größe sich zur laufzeit ergibt und ein vector ist ein "array" dessen größe sich wärend der laufzeit ändern kann, liege ich damit richtig?

    statisches Array - klar, groesse muss zur kompilezeit bekannt sein. Das ist die einschraenkung fuer den User. Die eigentliche Bosonderheit ist doch aber, das das Ding komplett aufn stack liegt ! Also die aufwendige dynamische Speicherverwaltung ned beansprucht wird.

    dynamisches Array - der Speicher fuer das Ding wird dynamisch erzeugt, also ueber die Speicherverwaltung. Dafuer braucht erst zur Laufzeit die groesse bekannt sein.

    std::vector - STL-Implementation eines Dynamischen Arrays mit ner Menge Komfort drumherum.

    Wenn jemand wirklich beruflich programmieren will/soll, find ich es schon sinnvoll, ihm mal paar standard klassen nachprogrammieren zu lassen. Jemand der mit dynamischen C-Arrays z.b. umgehen kann, tut sich viel leichter, kosten (Laufzeit) fuer die so tollen komfortfunktionen der STL und anderer Frameworks abzuschaetzen ....

    Ciao ...



  • RHBaum schrieb:

    ... kosten (Laufzeit) fuer die so tollen komfortfunktionen der STL und anderer Frameworks abzuschaetzen ....

    Ciao ...

    Welche Kosten meinst Du denn? Erkläre das mal am Beispiel eines std::vector .



  • RHBaum schrieb:

    std::vector - STL-Implementation eines Dynamischen Arrays mit ner Menge Komfort drumherum.

    kosten (Laufzeit) fuer die so tollen komfortfunktionen der STL und anderer Frameworks abzuschaetzen ....

    Hast du einen Beweis, das die Komfortfunktionen von vector Mehrkosten haben, als wenn man es selber implementiert?



  • so, das ursprüngliche problem ist gelöst

    Lösungsweg:

    habe dem array einen zusätzlichen wert verpasst und den array via schleife gezählt bis dieser wert drinnsteht

    mit der dadurch gewonnenen länge des arrays konnte ich durch new die richtige neue größe erstellen

    vielen dank nochmal an alle helfer

    PS: nette diskussion die hier vom zaune gebrochen ist, ich lese ausmerksam mit 😉



  • ast du einen Beweis, das die Komfortfunktionen von vector Mehrkosten haben, als wenn man es selber implementiert?

    Hab ich irgendwas von Mehrkosten gegenueber eines dynamischen Arrays geschrieben ?
    Ich meinte damit, das durch die "Komfortfunktionen" bei der STL, viele "Programmierer" sich weniger Sorgen machen, was genau da passiert !

    der Vector ist doch das perfekteste beispiel dafuer!

    Bei nem Dynamischen Array bin ich doch gezwungen, mir vorab gedanken zu machen, wie gross ich es machen muss, beim vector ?
    Wie oft sieht man, das nen Vector mitm standard Ctor angelegt wird und dann massenweisse daten "reingepumpt" werden ?
    Wer verwendet denn den Ctor wo ich ich schon mal die Groesse des puffers fuer den vector anlegen kann ?

    Wenn man selber mal ne Methode implementiert hat, wo nen Dynamisches Array "vergroessert" werden muesste, erinnert man sich vielleicht mal dran, beim naechsten std::vector::push_back ^^

    Ciao ...


Anmelden zum Antworten