Absturz aufgrund des Destruktors



  • Hi,

    hab folgendes Problem:
    hab hier eine Vektor-Klasse, die unter anderem 2 Vektoren addiert. Die Vektoren sollen auch addiert werden können, wenn sie unterschiedliche Dimensionen haben.
    Wenn ich bei unterschiedlichen Dimensionen aus den Funktionen gehe, ohne eine Berechnung durchzuführen, läuft das Programm komplett durch, wenn ich jedoch die Dimensionen berücksichtige, stürzt es beim Destruktor ab, aber wieso? Hier ein paar Code-Passagen:

    CVektorDbl::~CVektorDbl()
      {
       Destroy();
      }  // Destruktor
    
    void CVektorDbl::Destroy()
      {
       delete [] this->vek;
      }  // Destroy-Funktion
    

    Plus- & Minusfunktion mit unterschiedl. Dimensionen (Absturz!):

    CVektorDbl operator+(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	unsigned int dim_gr, dim_kl;
    
    	if(eins.dim>zwei.dim)
    	  {dim_gr=eins.dim; dim_kl=zwei.dim;}
    	else
    	  {dim_gr=zwei.dim; dim_kl=eins.dim;}
    			// Zwischenvariablen initiiert mit den Dimensionsgrößen
    
    	CVektorDbl erg(dim_gr);
    
    	for(unsigned int i=0; i<dim_gr; i++)
    	  {
    		erg.vek[i] = eins.vek[i] + zwei.vek[i];
    		if(i>dim_kl)
    		  {
    			if(dim_kl==eins.dim)
    				erg.vek[i]=zwei.vek[i];
    			if(dim_kl==zwei.dim)
    				erg.vek[i]=eins.vek[i];
    		  }
    	   }
    	return erg;
      }  // Überladung des "+"-Operators
    
    CVektorDbl operator-(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	unsigned int dim_gr, dim_kl;
    
    	if(eins.dim>zwei.dim)
    	  {dim_gr=eins.dim; dim_kl=zwei.dim;}
    	else
    	  {dim_gr=zwei.dim; dim_kl=eins.dim;}
    
    	CVektorDbl erg(dim_gr);
    
    	for(unsigned int i=0; i<dim_gr; i++)
    	  {
    		erg.vek[i] = eins.vek[i] - zwei.vek[i];
    		if(i>dim_kl)
    		  {
    			if(dim_kl==eins.dim)
    				erg.vek[i]=-zwei.vek[i];
    			if(dim_kl==zwei.dim)
    				erg.vek[i]=eins.vek[i];
    		  }
    	   }
    	return erg;
      }  // Überladung des "-"-Operators
    

    Plus- & Minusfunktionen vorher (kein Absturz):

    CVektorDbl operator+(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	CVektorDbl erg(eins.dim);
    
    	for(unsigned int i=0; i<erg.dim; i++)
    		erg.vek[i] = eins.vek[i] + zwei.vek[i];
    
    	return erg;
      }  // Überladung des "+"-Operators
    
    CVektorDbl operator-(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	CVektorDbl erg(eins.dim);
    
    	for(unsigned int i=0; i<erg.dim; i++)
    		erg.vek[i] = eins.vek[i] - zwei.vek[i];
    
    	return erg;
      }  // Überladung des "-"-Operators
    

    PS: wir sollen im Destuktor die Destroy-Fkt aufrufen, da es ja mal sein könnte :), dass wir eine Destroy-Fkt zwischendurch mal gebrauchen könnten...


  • Mod

    die definition der klasse und des konstruktors solltest du uns nicht vorenthalten. im übrigen

    for(unsigned int i=0; i<dim_gr; i++)
          {
            erg.vek[i] = eins.vek[i] + zwei.vek[i];
            if(i>dim_kl)
              {
                if(dim_kl==eins.dim)
                    erg.vek[i]=zwei.vek[i];
                if(dim_kl==zwei.dim)elemen
                    erg.vek[i]=eins.vek[i];
              }
           }
    

    hier kommt im falle unterschiedlicher dimensionen auf jeden fall undefiniertes verhalten ins spiel, denn du greifst bei einem der argumente auf elemente mit ungültigem index zu. du kannst nicht etwas undefiniertes tun und dann das im nachhinein zu korrigieren versuchen. im übrigen ist die bedingung im if ungenügend, denn der index i == dim_kl ist bereits ein ungültiger für ein argument.



  • so, hab jetzt auf anregung durch camper neue variablen eingefügt, damit ich (hoffentlich) nicht in den unbestimmten wertebereich gelange:

    CVektorDbl operator+(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	unsigned int dim_gr, dim_kl;
    	double t1, t2;
    
    	if(eins.dim>zwei.dim)
    	  {dim_gr=eins.dim; dim_kl=zwei.dim;}
    	else
    	  {dim_gr=zwei.dim; dim_kl=eins.dim;}
    			// Zwischenvariablen initiiert mit den Dimensionsgrößen
    
    	CVektorDbl erg(dim_gr);
    
    	for(unsigned int i=0; i<dim_gr; i++)
    	  {
    		if(i<=dim_kl)
    		  {
    			t1=eins.vek[i];
    			t2=zwei.vek[i];
            }
    
    		if(i>dim_kl)
    		  {
    			if(dim_kl==eins.dim)
               {
    				t2=zwei.vek[i];
    				erg.vek[i]=t2;
    				t1=0;
               }
    			if(dim_kl==zwei.dim)
    			  {
    				t1=eins.vek[i];
    				erg.vek[i]=t1;
    				t2=0;
               }
    		  }
    		erg.vek[i]=t1+t2;
    	   }
    	return erg;
      }  // Überladung des "+"-Operators
    
    CVektorDbl operator-(const CVektorDbl& eins, const CVektorDbl& zwei)
      {
    	unsigned int dim_gr, dim_kl;
    	double t1, t2;
    
    	if(eins.dim>zwei.dim)
    	  {dim_gr=eins.dim; dim_kl=zwei.dim;}
    	else
    	  {dim_gr=zwei.dim; dim_kl=eins.dim;}
    			// Zwischenvariablen initiiert mit den Dimensionsgrößen
    
    	CVektorDbl erg(dim_gr);
    
    	for(unsigned int i=0; i<dim_gr; i++)
    	  {
    		if(i<=dim_kl)
    		  {
    			t1=eins.vek[i];
    			t2=zwei.vek[i];
            }
    
    		if(i>dim_kl)
    		  {
    			if(dim_kl==eins.dim)
               {
    				t2=zwei.vek[i];
    				erg.vek[i]=t2;
    				t1=0;
               }
    			if(dim_kl==zwei.dim)
    			  {
    				t1=eins.vek[i];
    				erg.vek[i]=t1;
    				t2=0;
               }
    		  }
    		erg.vek[i]=t1-t2;
    	   }
    	return erg;
      }  // Überladung des "-"-Operators
    

    hier noch Konstruktor sowie klasse:

    CVektorDbl::CVektorDbl(unsigned int dim)
      {
    	Init(dim);
      }  // Standard-Konstruktor
    
    CVektorDbl::CVektorDbl(const CVektorDbl& vek)
      {
    	Init(vek.dim);
    	this->operator=(vek);
      }  // Kopier-Konstruktor
    
    void CVektorDbl::Init(unsigned int dim)
      {
     	this->dim  = dim;
    	this->vek  = new double[dim];
    
    	if (this->vek == NULL)
    	  {
    		cerr << "Kein Speicher mehr!!!" << endl;
    		exit(-1);
         }	
    	for(unsigned int i=0; i < this->dim; i++) this->vek[i] = 0;
      }  // Init-Funktion
    
    class CVektorDbl
      {
     private:
    	void Init(unsigned int dim);
    	void Destroy(void);
    
     public:
    	CVektorDbl(unsigned int dim=0);
    	CVektorDbl(const CVektorDbl&);
    
    	~CVektorDbl();
    .
    .
    .
     private:
    	unsigned int dim;
    	double *vek;
      };
    

    ich ruf z.b. die Minus-Funktion so auf:

    vek1=vek2-vek3;
    

    was mir aufgefallen ist, das programm stürzt nur ab, wenn z.b. vek3 die dimension 3 hat und vek2 die dimension 2, wenn sie die gleiche dimension haben, dann läuft das programm durch

    MfG
    MastaZulu


  • Mod

    if(i<=dim_kl)
    

    die bedingung ist immer noch nicht streng genug. den copy-zuweisungsoperator solltest du noch zeigen. auch gibt new niemals einen null pointer zurück - im fehlerfall wird eine exception vom typ std::bad_alloc geworfen.



  • hier der =-Operator:

    CFolge& CFolge::operator=(const CFolge& zuweisung)
      {
    	this->dim  = zuweisung.dim;
    	this->last = zuweisung.last; 
    	for(unsigned int i=0; i<zuweisung.last; i++)
    		this->folge[i] = zuweisung.folge[i];
    	this->last=zuweisung.last;
    
    	return *this;
      }  // überladene "="-Operator-Funktion
    

  • Mod

    wo kommen denn plötzlich last und folge her?



  • ah! falsches programm 😉 sorry:

    CVektorDbl& CVektorDbl::operator=(const CVektorDbl& gleich)
      {
    	this->dim = gleich.dim;		
    	for(unsigned int i=0; i<gleich.dim; i++)
    		this->vek[i] = gleich.vek[i];		
    			// Werte des "gleich"-Vektors zuweisen	
    
    	return *this;
      }  // Überladung des Zuweisungs-Operators
    


  • Das solltest du nochmal überarbeiten. Was passiert denn wenn die beiden Vektoren unterschiedliche Länge haben?


Anmelden zum Antworten