Arbeitsspeicher läuft voll durch Arrays



  • Hallo,
    ich habe eine Plugin geschrieben und dieses definitert mehrere arrays und befüllt diese in jedem Durchlauf, und sollte diese im nächsten Durchlauf wieder überschreiben.
    Dazu dachte ich an folgenden Code in den Definitionen:

    double *arr_lat, *arr_long, *arr_alt, *arr_speed;
    

    in meiner Funktion:

    arr_lat = new double [koordinaten_anzahl]; 
    	arr_long = new double [koordinaten_anzahl];
    	arr_alt = new double [koordinaten_anzahl];
    	arr_speed = new double [koordinaten_anzahl];
    

    und am Ende der Funktion:

    delete[] arr_lat, arr_long, arr_alt, arr_speed;
    

    Allerdings scheint es nicht zu funktionieren, da der genutze Arbeitsspeicher immer größer wird, nur wenn ich das Plugin deaktivere, hört das Wachstum auf.

    Hat jemand eine Idee, was hier falsch laufen könnte? Vielen Dank schonmal im Voraus.



  • Du gibst mit deiner Anweisung nur ein Array frei (der Komma-Operator gibt den letzten Ausdruck zurück).

    Kommas kannst du hier nicht verwenden. Schreibe stattdessen

    delete[] arr_lat;
    delete[] arr_long;
    delete[] arr_alt;
    delete[] arr_speed;
    

    Und verwende bitte [cpp]- statt [code]-Tags. 😉



  • hage2001 schrieb:

    delete[] arr_lat, arr_long, arr_alt, arr_speed;
    

    😃 😃 😃 Köstlich! 😃 😃 😃



  • danke für deine schnelle Antwort. Leider läuft der Speicher immer noch voll. muss ich irgendetwas beachten wenn ich zwischen allokieren und löschen mit den daten arbeite - z.b. pointer zurücksetzen oder sowas?



  • Du solltest einfach darauf achten, dass du den richtigen Speicher freigibst. Wenn du STL-Container verwendest, wird das viel einfacher und komfortabler. Ausserdem wäre eine Klasse, welche die vier Eigenschaften zusammenfasst, noch angebracht.

    Poste doch mal deine Funktion.



  • hage2001 schrieb:

    danke für deine schnelle Antwort. Leider läuft der Speicher immer noch voll. muss ich irgendetwas beachten wenn ich zwischen allokieren und löschen mit den daten arbeite - z.b. pointer zurücksetzen oder sowas?

    Nein.

    Du könntest std::vector<double> nehmen. Das hilft gegen Memory Leaks.
    (Und zur C- Interoperabilität, falls notwendig, &vec[0] benutzen.)
    Simon



  • aber wie kann ich den garantieren, dass ich den richtigen Speicher freigebe? Ich kenne ja lediglich den namen des Arrays, dass den Speicher belegt und wenn ich dieses Array lösche, müsste der Speicher nach meinem Verständnis wieder frei sein.

    Ich werde mich mal in die STL Container einlesen, aber eigentlich möchte ich nicht meine ganze Funktion wieder umbauen.

    @theta: wenn ich mit std::vector<double> arbeite, dann kann ich doch immer nur auf den obersten Wert greifen, oder?

    meine plugin ist so aufgebaut, dass ich zu Beginn koordinaten in ein array schreibe, dann immer 3 punkte rausnehme und damit eine kurve zwischen den vektoren errechne und diese kurvenpunkte dann wieder in ein neues array speichere und dann erfolgt eine umrechnung die wieder in einem neuen array gespeichert wird und aus diesem bezieht schlussendlich eine zeichnungsfunktion ihre daten und zeichnet.



  • Zeig halt mal Code && || probiers mit einem Minimalbeispiel.



  • aber wie kann ich den garantieren, dass ich den richtigen Speicher freigebe? Ich kenne ja lediglich den namen des Arrays, dass den Speicher belegt und wenn ich dieses Array lösche, müsste der Speicher nach meinem Verständnis wieder frei sein.

    Indem du dir die Zeiger auf den Speicher speicherst und freigibst, wenn er nicht mehr benötigt wird..

    Jeden Speicher, den du anforderst musst du auch wieder selbst freigeben. Zu jedem new/[] ein delete/[] .

    Die Arbeit mit dem std::vector< bool > wird auf Zeit sicher angenehmer sein, als mit einem händischen Array.



  • drakon schrieb:

    Jeden Speicher, den du anforderst musst du auch wieder selbst freigeben. Zu jedem new/[] ein delete/[] .

    Aber genauso habe ich es doch gemacht, oder etwa nicht?



  • Ähm, Code zeigen? Wahrscheinlich übersiehst du den Fehler.

    Scheisse, meine Bratkartoffeln



  • hage2001 schrieb:

    Aber genauso habe ich es doch gemacht, oder etwa nicht?

    Dafuer hast du wohl zu wenig Code gepostet, um das zu beurteilen. Hast du denn mal gezaehlt, wieviel new's und delete's du hast? Es zaehlen die Aufrufe!



  • hier mal der ganze code, die funktionsaufrufe habe ich rausgenommen, da die sehr groß sind.

    const int koordinaten_anzahl = 9;	// Für die Größe der Arrays - Einlesen aus FMS
    const int koordinaten_kurve_anzahl = (((koordinaten_anzahl-2) * 10) + 2);
    
    double *arr_lat, *arr_long, *arr_alt, *arr_speed, *arr_curve_lat, *arr_curve_long, *arr_curve_alt, *arr_curve_90_lat, *arr_curve_90_long, *arr_curve_90_alt, *arr_curve_270_lat, *arr_curve_270_long, *arr_curve_270_alt;
    double *arr_local_x, *arr_local_y, *arr_local_z, *arr_local_90_x, *arr_local_90_y, *arr_local_90_z, *arr_local_270_x, *arr_local_270_y, *arr_local_270_z;
    
    int DrawFunktion()
    {
    	arr_lat = new double [koordinaten_anzahl]; 
    	arr_long = new double [koordinaten_anzahl];
    	arr_alt = new double [koordinaten_anzahl];
    	arr_speed = new double [koordinaten_anzahl];
    
    	// Konstante Daten
    	arr_lat[0] = 47.261094444444446;
    	arr_long[0] = 11.352863888888889;
    	arr_alt[0] = 582;
    	arr_speed[0] = 50;
    	//... befüllen des Arrays nach diesem Muster
    
    	// Aufruf der Kurvenberechnung
    	arr_curve_lat = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_long = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_alt = new double [koordinaten_kurve_anzahl]; 
    
    	for(int ix = 0, iy = 0; ix != koordinaten_anzahl-2; ++ix, iy=iy+10)
    	{
    		Kurvenflug();
    	}
    
    	// Erzeugen der Begrenzungspunkte für die Checkpoints
    	arr_curve_90_lat = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_90_long = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_90_alt = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_270_lat = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_270_long = new double [koordinaten_kurve_anzahl]; 
    	arr_curve_270_alt = new double [koordinaten_kurve_anzahl]; 
    	int iy;
    	for(int ix = 0; ix != koordinaten_kurve_anzahl-1; ++ix)
    	{
    		Begrenzung();
    	}
    
    	// Umrechnung in X Plane Lokale Koordinaten (für alle Koordinaten)
    	arr_local_x = new double [koordinaten_kurve_anzahl]; 
    	arr_local_y = new double [koordinaten_kurve_anzahl]; 
    	arr_local_z = new double [koordinaten_kurve_anzahl]; 
    	arr_local_90_x = new double [koordinaten_kurve_anzahl]; 
    	arr_local_90_y = new double [koordinaten_kurve_anzahl]; 
    	arr_local_90_z = new double [koordinaten_kurve_anzahl]; 
    	arr_local_270_x = new double [koordinaten_kurve_anzahl]; 
    	arr_local_270_y = new double [koordinaten_kurve_anzahl]; 
    	arr_local_270_z = new double [koordinaten_kurve_anzahl]; 
    	for(int ix = 0; ix != koordinaten_kurve_anzahl; ++ix)
    	{
    		Umrechung();
    	}
    
    	// Aufruf der Zeichnungsfunktion
    	for(int ix = 0; ix != koordinaten_kurve_anzahl-1; ++ix)
    	{
    		Checkpoint();
    	}
    
    	// Speicher freigeben
    	delete[] arr_lat;
    	delete[] arr_long;
    	delete[] arr_alt;
    	delete[] arr_speed;
    	delete[] arr_curve_lat;
    	delete[] arr_curve_long;
    	delete[] arr_curve_alt;
    	delete[] arr_curve_90_lat;
    	delete[] arr_curve_90_long;
    	delete[] arr_curve_90_alt;
    	delete[] arr_curve_270_lat;
    	delete[] arr_curve_270_long;
    	delete[] arr_curve_270_alt;
    	delete[] arr_local_x;
    	delete[] arr_local_y;
    	delete[] arr_local_z;
    	delete[] arr_local_90_x;
    	delete[] arr_local_90_y;
    	delete[] arr_local_90_z;
    	delete[] arr_local_270_x;
    	delete[] arr_local_270_y;
    	delete[] arr_local_270_z;
    
    	return 0;
    }
    

    Ich hoffe das bringt uns weiter. Vielen Dank für eure Mithilfe schonmal.



  • hage2001 schrieb:

    hier mal der ganze code, die funktionsaufrufe habe ich rausgenommen, da die sehr groß sind...

    Bei deinem Code sträuben sich mir die Nackenhaare.
    1. Warum globale Variablen (Besser lokal mit Übergabeparametern an die Funktionen).
    2. Werte die zusammen gehören würde ich auch zusammenfassen. Sei es in eine einfache Struktur (im Sinne POD), oder falls Logik dazugehört in eine Klasse (im Sinne von Nicht-POD).
    2a) Wenn du diesen dann auch noch einen Konstruktor spendierst wird die Zuweisung wohl auch deutlich kürzer.
    3. Lange Funktionen neigen dazu unübersichtlich und unleserlich zu werden, ggf. solltest du die Funktion noch untergliedern (oder auf anderen Weg wie z.B. unter 2 angesprochen den Code reduzieren).



  • hage2001 schrieb:

    hier mal der ganze code, die funktionsaufrufe habe ich rausgenommen, da die sehr groß sind.

    Hier hast Du zu jedem new[] ein passendes delete[]. An dieser Funktion liegt's nicht.



  • An diesem Code liegt es wohl nicht.



  • double *arr_lat, *arr_long, *arr_alt, *arr_speed, *arr_curve_lat, *arr_curve_long, *arr_curve_alt, *arr_curve_90_lat, *arr_curve_90_long, *arr_curve_90_alt, *arr_curve_270_lat, *arr_curve_270_long, *arr_curve_270_alt; 
    double *arr_local_x, *arr_local_y, *arr_local_z, *arr_local_90_x, *arr_local_90_y, *arr_local_90_z, *arr_local_270_x, *arr_local_270_y, *arr_local_270_z;
    

    die können auch in der funktion (DrawFunction) stehen, ich hatte sie gerade nur rauskopiert. gibt es noch eine andere möglichkeit rauszufinden, wo der speicher vollläuft?

    die unterfunktionen sind es auch nicht, die habe ich schon einzeln auskommentiert und getestet. nur wenn ich die ganze DrawFunction rausnehme läuft der Speicher nicht voll.



  • valgring kann das, gibt es aber nur fuer Linux. Auch wird wohl sowas bei Visual Studio mitgeliefert sein.



  • also für linux das tool habe ich gefunden, aber bei ms visual studio 2008 (das nutze ich) habe ich nicht finden können, vielleicht hab ichs aber auch einfach nur nicht erkannt...jemand ne idee?



  • Kommentier halt noch nacheinander die DrawFunction() aus...


Anmelden zum Antworten