Absturz bei Freigabe von Speicher



  • Hallo liebes Forum,

    ich hab ein Problem mit folgendem Programm:

    void leseAusZeus(char *dateinameQuelle, int xBereich, int zStart, int zEnde, int tBereich, int takt, float ***aaafErgebnisse){
    	// Notwendig zum nutzen der UTzeusviGetRawData-Funktion
    	int *aiPosition = new int [xBereich];
    	float **aafAmplitude;
    	aafAmplitude = new float* [xBereich];
    	for(int x = 0; x <xBereich; x++){
    		aafAmplitude[x] = new float [tBereich];
    		for(int t = 0; t < tBereich; t++){
    			aafAmplitude[x][t] = 0.0f;
    		}
    	}
    	if((takt > 3) || (takt < 0))
    		std::cout << "Fehler" << std::endl;
    	else{
    		for(int iz = 0; iz < (zEnde - zStart); iz++){
    			UTzeusviGetRawData(dateinameQuelle, 0, xBereich, &aiPosition[0], zStart + iz, 0, takt, tBereich, &aafAmplitude[0][0]);
    			for(int ix = 0; ix < xBereich; ix++){
    				for(int zeit = 0; zeit < tBereich; zeit++){
    					aaafErgebnisse[ix][iz][zeit] = aafAmplitude[ix][zeit];
    				}
    			}
    		}
    	}
    	delete[] aiPosition;
    	for(int x = 0; 0 < xBereich; x++)
    		delete[] aafAmplitude[x];
    	delete[] aafAmplitude;
    }
    

    und zwar wird mir beim Debuggen an Zeile 26 gesagt, dass versucht wird in geschützten Speicher zu schreiben und das Programm stürzt ab. Zwischendurch wurde mit Hilfe der Funktion UTzeusviGetRawData eine zweidimensionales Feld (aafAmplitude) aus einer Datei geladen und dem dreidimensionalen Feld (aaafErgebnisse) übergeben.

    Kann mir jemand sagen, warum ich den Speicher nicht freigeben kann?



  • Hallo,
    deine Schleife in zeile 25 ist eine Endlosschleife!
    Vergleiche mal Zeile 25 mit Zeile 6, dann wird dir ein kleiner Unterschied auffallen.



  • Das geht schon so. Wenn auf Schleifen, if-Bedinungen etc. nur eine Anweisung folgt, kann auf die Klammern verzichtet werden. Die Fehlermeldung kommt auch schon bei x = 0. Der Vollständigkeit halber hab ich mal die Klammern in meinem Programm hinzu gefügt und wie erwartet kam die Fehlermeldung an der selben Stelle.



  • Das meinet er nicht. Du hast da

    for(int x = 0; 0 < xBereich; x++)
    

    stehen, aber du willst da

    for(int x = 0; x < xBereich; x++)
    

    stehen haben.





  • Kommentier mal den Bereich von Zeile 12 bis 23 aus.
    Wenns nun läuft, liegt der Fehler wohl in diesem Abschnitt, vermutlich der Dreifachpointer.
    Vorausgesetzt Zeile 25 sieht nun tatsächlich so aus:

    for(int x = 0; x < xBereich; x++)
    


  • Ja, ohne den Abschnitt funktioniert es. Es reicht auch schon Zeile 16 weg zu lassen, aber das hilft mir nicht weiter. Die Funktion UTzeusviGetRawData liegt in einer dll und mehr als ihre grobe funktionsweise ist mir nicht bekannt.
    Ich verstehe nicht, wieso ich auf einmal nicht mehr den Speicher freigeben kann.



  • Wie äußert sich denn der Fehler? Hängt sich das Programm auf, oder wird eine Exception geworfen?


  • Administrator

    Womöglich wurde in UTzeusviGetRawData über die Speichergrenzen hinaus geschrieben. Dadurch gab es eine Heap-Korruption und es wird undefiniertes Verhalten ausgelöst, was schlussendlich zu einem Absturz bei der Speicherfreigabe führt. Bist du sicher, dass du UTzeusviGetRawData richtig verwendest?

    Grüssli



  • @ Fusel Factor: Ja, ich bekomme eine System::AccessViolationException.
    @ Dravere: So viel ich weiß ja. Wenn ich ein festes Array definiere funktioniert es auch, nur leider weiß ich die benötigte Größe für das Array nicht von vorn herein. Diese Methode ist am Ende auch wieder Teil einer dll. Für den Fall, dass in UTzeusviGetRawData über die Grenzen hinaus geschrieben wird, hab ich es mal mit einem wesentlich größeren Array versucht als darin eigentlich benötigt wird, aber es funktioniert trotzdem nicht.



  • UTzeusviGetRawData(..., ..., ..., ..., ..., ..., ..., ..., &aafAmplitude[0][0]);
    

    UTzeusviGetRawData erwartet nicht zufällig ein eindimensionales Array als letzten Parameter? Oder zumindest eine Speicherstruktur, die linear im Speicher liegt?
    Dein dynamisch aufgebautes Array liegt nämlich wild im Speicher verteilt. Soll heißen: aafAmplitude[1][0] liegt nicht zwangsläufig direkt hinter aafAmplitude[0][tBereich-1] sondern u.U. an einer völlig anderen Stelle.



  • Also ich gehe davon aus, dass UTzeusviGetRawData einen Zeiger auf ein komptaktes 2-D Array erwartet als letztes Argument und darum der Aufruf mit einem dynamischen 2-D-Array (welches überall im Speicher verteilt liegt oder zumindest noch die array-counts dazwischen liegen) fehlschlägt. Dann würden diese internen Zähler nämlich überschrieben und delete[] könnte das falsche tun.
    Aber ist nur meine Theorie, ich kenne die Funktion ja nicht.

    Viele Grüße,
    Michael

    PS: Tachyon war irgendwie schneller 🙂



  • @Tachyon und @Decimad: Genau so sei es gewesen. Tausend Dank für eure Hilfe!


Anmelden zum Antworten