Speicherleck...



  • Hi zusammen!

    Ich hab in der unten stehenden Klasse (cpp-Datei) wohl ein sehr großes Speicherleck... Ich denke, es hat irgendwas mit copy-Konstruktor und Destruktor zu tun. So ganz check ich das damit noch nicht. Könntet ihr deswegen bitte mal gucken, ob ihr da spontan was findet? Würde mich (wie immer!) sehr darüber freuen!!

    Ich denke, wichtig sind nur folgende Methoden:

    Vektor const& Vektor::operator=(Vektor const& v);
    Vektor::~Vektor();
    Vektor::Vektor(int n);
    init(int n);
    

    Letztendlich führe ich einfach nur folgende Schleife aus, die dann riesig viel Speicher braucht:

    Vektor grad;
    for(i=0;i<1000000;i++) grad = gradient(db,modell);
    

    Vielen Dank & Grüße,

    Tobias

    #include "StdAfx.h"
    #include "FitMeDLL.h"
    
    // =======================================================
    // Konstruktor & Destruktor
    // =======================================================
    
    Vektor::Vektor() {
    	v = NULL;
    	this->n = 0;
    }
    
    // Speicher allokieren
    void Vektor::init(int n) {
    	v = new double[n];
    	for(int i=0;i<n;i++) { 
    		v[i] = 0.0;
    	}
    	this->n = n;
    }
    
    Vektor::Vektor(int n) {
    	v = NULL;
    	init(n);
    }
    
    Vektor::Vektor(double v, int n) {
    	v = NULL;
    	init(n);
    	for(int i=0;i<n;i++) {
    		this->v[i] = v;
    	}
    }
    
    Vektor::~Vektor() {
    	if( v!=NULL ) delete [] v;
    	n = 0;
    	return;
    }
    
    Vektor::Vektor(const Vektor &v) {
    	this->v = NULL;
    	init(v.n);
    	set(v);
    	return;
    }
    
    // =======================================================
    // Funktionen
    // =======================================================
    
    void Vektor::set(double v, int i) {
    	if( i<0 || i>=n ) return; // Fehler
    	this->v[i] = v;
    }
    
    double Vektor::get(int i) {
    	if( i<0 || i>=n ) return INF; // bei Fehler: unendlich
    	return this->v[i];	
    }
    
    int Vektor::getDim() {
    	return n;
    }
    
    double Vektor::norm() {
    	return sqrt( this->skal(this) );
    }
    
    double Vektor::norm(Vektor v) {
    	return sqrt( this->skal(&v) );
    }
    
    Vektor Vektor::copy() {
    	Vektor v(n);
    	for(int i=0;i<n;i++) {
    		v.set( get(i), i);
    	}
    	return v;
    }
    
    void Vektor::print() {
    	printf("=== Vektor:\n");
    	printf("- Dimension: %i\n",n);
    	for(int i=0;i<n;i++) {
    		printf("%i: %10.5f\n",i,get(i));
    	}
    }
    
    double Vektor::summe() {
    	double sum = 0;
    	for(int i=0;i<n;i++)
    		sum += get(i);
    	return sum;
    }
    
    Vektor Vektor::absolut() {
    	Vektor v(n);
    	for(int i=0;i<n;i++) {
    		v.set( abs(get(i)) , i);
    	}
    	return v;
    }
    
    void Vektor::set(Vektor const& v) {
    	for(int i=0;i<n;i++) {
    		set( v.v[i] , i );
    	}
    }
    
    double Vektor::max() {
    	double max = 0.0;
    	for(int i=0;i<n;i++) {
    		if( v[i]>max ) max=v[i];
    	}
    	return max;
    }
    
    // =======================================================
    // Operatoren
    // =======================================================
    
    Vektor Vektor::add(Vektor v, double adder) {
    	Vektor vRet(INF,n);
    	if( v.getDim()!=n ) return vRet; // unendlich-Vektor wenn Dimensionen nicht stimmen!
    	for(int i=0;i<n;i++) {
    		vRet.set( get(i) + adder * v.get(i) , i );
    	}
    	return vRet;
    }
    
    // Vektor + Vektor
    Vektor Vektor::operator+(Vektor v) {
    	return add(v, +1.0 );
    }
    
    // Vektor + Vektor
    Vektor Vektor::operator-(Vektor v) {
    	return add(v, -1.0 );
    }
    
    // Vektor * Zahl
    Vektor Vektor::operator *(double v) {
    	Vektor vRet(n);
    	for(int i=0;i<n;i++) {
    		vRet.set( get(i) *v , i );
    	}
    	return vRet;	
    }
    
    // Vektor / Zahl
    Vektor Vektor::operator /(double v) {
    	Vektor vRet(n);
    	for(int i=0;i<n;i++) {
    		vRet.set( get(i) /v , i );
    	}
    	return vRet;	
    }
    
    // intern, wird wegen Zeiger (*v) mehrfach benötigt!
    double Vektor::skal(Vektor* v) {
    	if( v->getDim()!=n ) return INF; // unendlich, wenn Dimensionen nicht stimmen!
    	double skal = 0.0;
    	for(int i=0;i<n;i++) {
    		skal += get(i) * v->get(i);
    	}
    	return skal;
    }
    
    // Skalarprodukt
    double Vektor::operator *(Vektor v) {
    	return this->skal(&v);
    }
    
    Vektor const& Vektor::operator=(Vektor const& v) {
    	init(v.n);
    	set(v);
    	return *this;
    }
    


  • Das Leck ist im Zuweisungsoperator. Du gibst den alten Vektorinhalt nicht frei, bevor du den neuen allozierst. Es gibt da noch einige weitere Fallstricke, einen operator= kann man nicht einfach so nebenher machen, wenn man nicht weiß was man tut. Zum Glück ist das in so ziemlich jedem C++-Buch beschrieben ...


Anmelden zum Antworten