Stringstream und dynamisches Array



  • N8i Nexus,

    selbst n neudefinierten string hat er nicht genommen -.-

    UPDATE: oh ich glaube ich habs, krass -.- wenn ich den Stream vor jedem getline. mit Clear() lösche scheint es zu funktionieren.



  • Hast du tatsächlich bis spät in die Nacht an dem rumprobiert? 😃

    Mit stringstream::clear() setzt du nur die Fehlerflags zurück, was heisst, dass irgendwo etwas schiefgelaufen ist. Du solltest dich vielleicht schon darum kümmern, denn Ignorieren von Fehlern ist nicht immer das Wahre...



  • Hallo, ich wollte ungern deswegen einen neuen Thread aufmachen und versuch es hier als Anhang.

    Ich hab nun nach der While-Schleife veruscht den Speicher des Arrays wieder freizugeben. Dies klappt bis zu einem bestimmten Punkt dann erfolgt eine Fehlermeldung, das der Heap kaputt sei.

    // Speicherplatz wieder freigeben
    	// in umgekehrter Reihenfolge
    
    	// Spalten der I-ten Zeile
    	for(int i = 0; i < iZeilen; i++)
    	{
    		delete dynarray[i];
    	}
    	delete [] dynarray;   // <-- nach dieser Anweisung sagt er mir "HEAP Corrupton ERROR"
    

    Wordurch wird das verursacht? Wie kann ich das vermeiden oder umgehen? Habe ich etwas übersehen?



  • Du hast ja ein zweidimensionales Array, behandelst es aber bei der Freigabe wie ein eindimensionales.

    Richtig wäre:

    for(int i = 0; i < iZeilen; ++i)
    {
        for (int j = 0; j < iSpalten; ++j)
        {
            delete dynarray[i][j];  // 2. Dimension löschen
        }
        delete[] dynarray[i];       // 1. Dimension löschen
    }
    delete[] dynarray;              // 0. Dimension löschen
    


  • jo, ich hab die n8 dran gehockt und gelesen und gelesen ^^

    ich hab mal den Code etwas gekürtzt um die Fehlerstellen besser zu finden.

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    using namespace std;
    
    int main(int argc, char** argv)
    {
    
    	// Datei zum Lesen öffnen
    	ifstream stream("eingabe.txt");
    	if( stream.is_open() != true )
    	{
    	cout << "Fehler beim Datei nicht öffnen!\n" << endl;
    	};
    
    	string sBuffer;
    	istringstream isZahl;
    
    	int iSpalten = 0;		// Anzahl der Spalten
    	int iZeilen = 0;		// Anzahl der Zeilen
    
    	bool isMatrixRead = false;
    	int** dynarray = NULL;
    
    	int icnt = 1;
    
     	while(getline(stream, sBuffer))
    	{
    		isZahl.str(sBuffer);
    
    		if(icnt == 1)
    		{
    
    			isZahl >> iZeilen;
    			isZahl >> iSpalten;
    
    			dynarray = new int* [iSpalten];	// Platz für Zeilen reservieren
    
    			// int** -> dyanarray[0]
    			//			dyanarray[1]
    
    			// Nun Speicher fuer die Spalte reservieren
    			for(int i = 0; i < iZeilen; i++)
    					dynarray[i] = new int [iSpalten];			// Speicherplatz für die Spalten reservieren
    
    			// int** -> dyanarray[0] --> dyanarray[0][0] dyanarray[0][1]
    			//			dyanarray[1] --> dyanarray[1][0] dyanarray[1][1]
    
    		}else if (!isMatrixRead)
    		{
    			for(int i = icnt-2; (i < icnt-1 && i < iZeilen);i++ )
    			{
    				for(int k = 0; k < iSpalten; k++)
    				{
    					isZahl >> dynarray[i][k];
    				}
    			}
    			if(icnt-2 == iZeilen)
    				isMatrixRead = true;
    
    		}
    		//isZahl.clear();
    		icnt++;
    	}
    	// Speicherplatz wieder freigeben
    	// in umgekerhter Reihenfolge
    
    /*	
    	for(int i = 0; i < iZeilen; i++)
    	{
    		for(int j = 0; j < iSpalten; j++)
    		{
    			delete dynarray[i][j];
    		}
    		delete[] dynarray[i];
    	}
    	delete [] dynarray;
    */
    return 0;
    }
    

    Die Anweisung "delete dynarray[i][j]" mag er nicht da Objekte die keine Zeiger sind nicht gelöscht werden können.



  • Sorry, ich hatte deine Speicheranforderung falsch im Kopf.

    Schau mal im Code:

    dynarray = new int* [iSpalten]; // Dimension iSpalten
    // ...
    for(int i = 0; i < iZeilen; i++) 
        dynarray[i] = new int [iSpalten]; // auch Dimension iSpalten
    

    Ich weiss nicht, wie du das 2D-Array organisierst, aber eine der beiden Dimensionen muss die Zeilen- und die andere die Spaltenanzahl sein.

    Was den Stream betrifft, seh ich gerade nichts. Geh mit einem Debugger schrittweise durch und überprüf die Fehlerflags, dann siehst du auch, wo der Fehler auftritt.

    Beim FileStream könntest du auch if(!stream) schreiben.


  • Administrator

    Der Fehler mit dem Stream ist wohl sehr trivial.
    Teste mal ob eof() true zurück gibt. Ich bin mir ziemlich sicher, dass er das tut. Du liest Werte aus und der Stream kommt ans Ende und setzt dann das Flag EOF, was ein Fehler ist und man kann aus dem Stream nichts weiteres mehr auslesen.
    Falls wirklich das EOF Flag gesetzt ist, dann ist der Aufruf von clear() gar nicht so verkehrt 😉

    Grüssli



  • Also wie das 2D-Array aufgebaut werden sollte, hab ich mir folgendes szenario angeschaut:

    Bild:
    http://www.hs-augsburg.de/~sandman/c_von_a_bis_z/bilder/16_10.gif

    Bezüglich des EOF.Flags werd ich gleich nochmal guggn.



  • Das EOF-Flag szenario:

    Nachdem er die ersten beide Werte aus dem Stream in die Variablen kopiert hat, setzt er das EOF-Flag. Das EOF-Flag bleibt gesetzt bis eine Clear-Anweisung kommt.

    Das hat aber auch nur Auswirkung beim Auslesen des Streams -.- der Inhalt des Streams wird angepasst.

    Nun bleibt nur noch die spannende Frage wieso nun mein kleines Array rum zickt.

    wird vlt. wieder eine lange N8 ^^


  • Administrator

    Noch kurz Zeit gehabt, dein zweites Problem anzuschauen:

    int main()
    {
        // Beispiel-Erstellung:
        int** pArray = new int*[5];
    
        for(int i = 0; i < 5; ++i)
        { pArray[i] = new int[10]; }
    
        // Beispiel-Zerstörung:
        for(int i = 0; i < 5; ++i)
        { delete[] pArray[i]; } // Hier war glaub ich der Fehler. Ein delete[] wird benötigt und nicht ein simples delete.
    
        delete[] pArray;
    }
    

    Ich glaube damit sollten alle Probleme behoben sein, oder?
    Anstatt C-Arrays könntest du auch std::vector nehmen, dann würden solche delete Probleme erst gar nicht auftauchen :p

    Grüssli


Anmelden zum Antworten