Wie Konstruktor bauen - brauche Pointer



  • Wenn du eine Methode aufrufen willst, brauchst du ein Objekt, auf das du dich beziehen kannst - wo das liegt, ist egal:

    //Objekt auf dem Stack:
    Matrix o;
    o.print();
    
    //Objekt auf dem Heap:
    Matrix* p = new Matrix;
    p->print();
    

    Ausnahme sind statische Methoden (in der Klassendefinition als 'static typ func(...);' angegeben), die kannst du auch ohne ein zugehöriges Objekt per "Matrix::create();" aufrufen.



  • Danke,

    jetzt bekomme ich aber einen haufe an segfaults.
    Folgender Code:

    Index_Set::Index_Set()
    {
    
    }
    
    Index_Set::Index_Set(int len)
    {
    	idcs = NULL;
    	len = len;
    	idcs = new int[len];
    }
    
    Index_Set::~Index_Set()
    {
    
    }
    
    //Index_Set.h
    		///Ctor
    		Index_Set();
    		Index_Set(int len);
    
    		///Dtor
    		~Index_Set();
    
    		//Member variables
    		///The index set array
        	int 	*idcs; 
    
    		///Lenght of the index set
    		int		len;
    

    wird so benutzt:

    // Extract pattern from pattern matrix  
    	// Create the Index Set J
    	J_pattern = o_sub.Get_J_Set(P, col);
    	// Copy the values into the big working Index_Set J
    	memcpy(J->idcs, J_pattern->idcs, J_pattern->len * sizeof(int));
    	J->len = J_pattern->len;
    

    und in Get_J_Set(P,col) folgendes

    template <class T> 	Index_Set* 	
    Spai_Sub<T>::Get_J_Set(	Pattern	 	*P,
    					const int 	col)
    {
    	Index_Set	*J = NULL;
    	J = P->j_sets[col];	
    	return J;
    }
    
    das pattern wird so gefüllt:
    [cpp]
    for( int col = 0; col < n; col++)
    	{
    		i_set = new Index_Set(1);
    		i_set->idcs[0] = col;
    		P->j_sets[col] = i_set;
    	}
    

    [/cpp]



  • achja,
    J und J_pattern sind natürlich schon initialisiert vorher:

    Index_Set 	o_is,
     				*J_pattern = NULL,
     				*J = NULL, 
    				*I = NULL;
    
    	// J will be filled with the
    	// new J values from pattern
    	// and will be updated each augmenting 
    	// step.
    	J = new Index_Set(A->n);	
           // Extract pattern from pattern matrix  
    	// Create the Index Set J
    	J_pattern = o_sub.Get_J_Set(P, col);
    	// Copy the values into the big working Index_Set J
    	memcpy(J->idcs, J_pattern->idcs, J_pattern->len * sizeof(int));
    	J->len = J_pattern->len;
    

    und das Pattern hat sowas als Member:

    /// All index sets of each column
        	Index_Set 	**j_sets;
    
    		/// The length of the pattern - always size n of
    		/// matrix A
    		int 		len;
    


  • Woher kommt eigentlich P und wie wurde es angelegt?

    (btw, hast du früher mal mit Java gearbeitet?)



  • Ne hab wenig mit Java gemacht.

    P wird so angelegt:

    Pattern::Pattern(int len)
    {
    	j_sets = NULL;
    	len = len;
    	j_sets = new Index_Set*[len];	
    }
    
    P = new Pattern(n);
    


  • Es liegt irgendwie am memcpy...ich weiß nicht warum...



  • Und wo genau kommt der Segfault? (ich würde ja darauf tippen, daß die Größenangaben nicht ganz zusammenpassen)

    PS Nur am Rande: In C++ verwendet man Pointer eher selten - wenn machbar, solltest du deine Variablen auf dem Stack unterbringen. Und die Zugriffe auf Membervariablen sollten lieber von der Klasse selbst übernommen werden.



  • Nene - an den Längen kanns nicht liegen - es hat ja alles funktioniert bis ich jetzt den Konstruktor geändert hatte. An den Längen hab ich nix verändert.

    Der segfault kommt genau beim memcpy() und schreit so:

    Conditional jump or move depends on uninitialised value(s)
    ==7389==    at 0x4022E6C: memcpy (mc_replace_strmem.c:406)
    ==7389==    by 0x804A1CE: Sp<double>::SP_Column(Matrix<double>*, Matrix<double>*&, Pattern*, int, double, int, int) (in /Source_code/Current/bin/sp)
    ==7389==    by 0x80497D2: main (in /Source_code/Current/bin/sp)
    

    Hmm....



  • Ich tippe immer noch auf eine Index-Überschreitung oder einen nicht-initialisierten Zeiger.

    Vorschlag: Erklär mal, was du überhaupt vorhast. Vielleicht wird der Quelltext dann klarer. (btw, anstelle der nackten Zeiger würde ich lieber mit std::vector<> arbeiten)



  • Ja ich weiß dass es in C++ schöne Templates gibt wie vector oder Set. Aber ich brauche wirklich das hier.

    Was ich vorhabe ist eigentlich trivial: Ein array in ein anderes kopieren.

    Also ich habe 2 Index_Sets und möchte von dem einen Index_Set->idcs array die werte in das andere kopieren Index_Set->idcs.

    Das erste wird so initialisiert dass es vom Pattern welches ein array aus Index_Sets hat einfach eine Index_Set extrahiert wird und an J_pattern übergeben wird.
    J (also das zweite array wohin kopiert werden soll) wird einfach so initialisiert:

    Index_Set* J = new Index_Set(n);

    J_pattern wird so gefüllt:

    template <class T>     Index_Set*    
    Spai_Sub<T>::Get_J_Set(    Pattern         *P,
                        const int     col)
    {
        Index_Set    *J = NULL;
        J = P->j_sets[col];   
        return J;
    }
    

    Das Pattern füllt seine j_sets so:

    Pattern 	*P = new Pattern(n);
    
    	for( int col = 0; col < n; col++)
    	{
    		i_set = new Index_Set(1);
    		i_set->idcs[0] = col;
    		P->j_sets[col] = i_set;
    	}
    

    wobei der Konstruktor so aussieht:

    Pattern::Pattern(int len)
    {
    	j_sets = NULL;
    	len = len;
    	j_sets = new Index_Set*[len];	
    }
    

    Die Member von Pattern:

    /// All index sets of each column
        	Index_Set 	**j_sets;
    
    		/// The length of the pattern - always size n of
    		/// matrix A
    		int 		len;
    

    das ganze wird so aufgerufen:

    Index_Set 	/*o_is,*/
     				*J_pattern = NULL,
     				*J = NULL, 
    				*I = NULL;
    
    	J = new Index_Set(A->n);		
    
    	J_pattern = o_sub.Get_J_Set(P, col);
    
    	// Copy the values into the big working Index_Set J
    	memcpy(J->idcs, J_pattern->idcs, J_pattern->len * sizeof(int));
    	J->len = J_pattern->len;
    


  • Woher kommen denn die Größenangaben n und l?

    (und was genau spricht dagegen, vector'en anstelle der dynamischen Arrays zu verwenden?)



  • das l ist eine eins als "1".

    das n ist gesetzt. Ich habe es gerade ausgeben lassen.

    Ich benutze keine std::vectoren aus einem Grund der vielleicht lächerlich erscheint - aber ich arbeite an einem zeitperformanten programm - und ich hatte mit der std-lib schon einige probleme damals gehabt die mein programm unglaublich langsam werden ließen. Ich hatte es damals umgeschrieben auf reine pointer-arithmetik ohne std-lib und es war viel schneller. Der ein oder andere mag jetzt sagen: Jaja-das lag wohl eher an der umschreibung und nicht an der std-lib. Mag sein - aber nochmal will ich mir das nicht antun. Soviel dazu.



  • ok, es liegt definitiv daran das J_pattern->len nicht gesetzt ist.
    Aber warum?



  • Lass dir doch mal J_Pattern->len und J->len ausgeben



  • AAAArgh.

    Ja klar, sowas geht ja nicht:

    Index_Set::Index_Set(int len)
    {
    	idcs = NULL;
    	len = len;
    	idcs = new int[len];
    }
    

    sondern nur sowas 🙂

    Index_Set::Index_Set(int len_a)
    {
    	idcs = NULL;
    	len = len_a;
    	idcs = new int[len];
    }
    

Anmelden zum Antworten