SOLVED: Brauche einen Rat beim Debuggen...



  • Ich brauche einen Rat zum Debuggen

    Hallo.

    Ich verzweifle langsam. Ich habe ein recht komplexes Programm (für meine Verhältnisse) geschrieben.
    Dabei wird ein 3D Gitter eingeladen. Es wird gerendert, wobei das Gitter in Volumenelemente unterteilt wird die
    wiederum aus Flächen bestehen - Knoten, Polyeder, Polygone, etc. Es werden Normalenvektoren und Volumeninhalt berechnet...
    und irgendwo dort scheine ich einen Fehler zu machen - denn im Laufe dieses Prozesses überschreibt ein realloc Befehl auf einen
    komplett undabhängigen Zeiger einen zuvor korrekt berechneten und abgespeicherten Wert.

    Konkret:
    Ich lade ein Gitter - einige Tausend Knoten, Flächen und Volumenzellen ein.
    Der Interpolationsfakor für Knoten 359 N[359].Interpolationsfaktor[3] wird korrekt zu 0.25 berechnet.

    ...es vergeht viel Code...

    Dann kommt ein realloc Befehl auf einen komplett anderen Zeiger.
    Und aus Knoten N[359].Interpolationsfaktor[3] = 0.25 wird
    N[359].Interpolationsfaktor[3] = 9.12e-008.
    Ansonsten bleibt alles korrekt.

    Ich stelle aber gerne den konkreten Fall ein:

    for (i = 0; i < 8; i++){ 
            printf("N[359].Gamma[3] = %2.4e\n", N[359].Gamma[3]); /*Liefert 0.2500e000*/
    	    FB->FBox[i].F_Thread = (TFace**)realloc(FB->FBox[i].F_Thread, FB->FBox[i].npFace * sizeof(TFace*)); /*Hier wird der Wert überschrieben*/ 
            printf("N[359].Gamma[3] = %2.4e\n", N[359].Gamma[3]); /*Liefert 9.12e-008*/
    	    if (FB->FBox[i].F_Thread == NULL){ printf("ERROR - Unable to allocate memory!\n"); getchar(); return 1; }
    	    FB->FBox[i].npFace = 0;
    
            switch(i){
                case 0:
                    /*....
                    ....
                    ....*/
            }
    	}
    

    Ich habe keine Ahnung, wie ich das Debuggen soll. Ich nutze Visual Studio 2015 - wie geht man da strategisch vor? Welche Werkzeuge kann man da nutzen, denn ich kann ja nicht wirklich in die malloc bzw. realloc Funktion hinein sehen.

    Ich habe auch mal das realloc durch ein malloc ersetzt, den alten Zeiger zwischengespeichert und die Werte "manuell" rüber geschrieben - aber da geschieht genau das gleiche.

    Ich kann hier nicht den kompletten Code posten, der wäre hunderte Seiten lang.



  • Du musst in malloc in realloc auch nicht reinschauen (man könnte aber einen anderen Speichermanager reinhängen, in den man reindebuggen kann). Die ganzen Indexzugriffe sind schon mal verdächtig, du solltest mal drüberschauen, ob die auch wirklich stimmen und das machen, was du denkst.



  • Die ganzen Indizes funktionieren bei anderen Dateien, bei Millionen von Knoten. Die Ergebnisse sind - bis auf diesen einen Knoten - korrekt. Es geht um hunderte Seiten, ich kann die nicht alle nochmal durchschauen. Ich arbeite an diesem Programm seit etwa einem Jahr. Und die ein oder andere Methode wurde sicher auch mit Streichhölzern zwischen den Augenliedern geschrieben.

    Ich weiß nicht, wie ich mich zu dem Fehler hin arbeiten kann. Die Debug-Möglichkeiten sind beschränkt, da der Code in einer DLL steht, welche ich über eine in C# geschriebene GUI aufrufe. Ich kann aber Text aus der DLL in der GUI ausgeben. Haltepunkte kann ich nicht setzen.

    Die goldene Frage ist, was löst diesen Fehler bei realloc oder malloc aus. Welche in welcher Methode läuft vielleicht auch der Index über den Berech hinaus.



  • FB->FBox[i].F_Thread = (TFace**)realloc(FB->FBox[i]->F_Thread, FB->FBox[i].npFace * sizeof(TFace*));
    

    - FB->FBox[i].F_Thread ist ungleich FB->FBox[i]->F_Thread
    - realloc Cast benutzen nur Deppen
    Was ist denn N für eine Krücke?
    Für Anfänger verbieten sich Makros und dergleichen.



  • CJens schrieb:

    Die Debug-Möglichkeiten sind beschränkt, da der Code in einer DLL steht, welche ich über eine in C# geschriebene GUI aufrufe.

    Ja und? VS kann mixed mode debugging.

    Ich glaub nicht, dass es ein Fehler in malloc ist, das ist sicher ein Fehler bei dir.
    Du kannst es vielleicht eingrenzen, indem du zuerst irgendwo schreibst if (wert == ...) oder etwas ähnliches, damit du einen Breakpoint setzen kannst, wenn der falsche Wert geschrieben wird.



  • Wutz schrieb:

    FB->FBox[i].F_Thread = (TFace**)realloc(FB->FBox[i].F_Thread, FB->FBox[i].npFace * sizeof(TFace*));
    

    - FB->FBox[i].F_Thread ist ungleich FB->FBox[i]->F_Thread

    Ja, deshalb sollte man den Text immer mit Strg+C kopieren. Der Fehler lag in meinem Post, nicht im Code.

    Wutz schrieb:

    - realloc Cast benutzen nur Deppen

    Ich würde auf den Cast gerne verzichten. Wo kann ich das einstellen, dass der Compiler sich darüber nicht beschwert?

    Wutz schrieb:

    Was ist denn N für eine Krücke?

    Ein Knoten vom benutzerdefinierten Typ TNode. Und N.Gamma ist ein double* welches auf ein Feld mit vier double zeigt.



  • Mechanics schrieb:

    Ja und? VS kann mixed mode debugging.

    Ich hab mixed mode debugging auch drinnen. Wenn ein Fehler ausgelöst wird, springt er auch (meistens) dort hin. Aber ich kann - warum auch immer - keine Haltepunkte anfahren.

    Mechanics schrieb:

    Ich glaub nicht, dass es ein Fehler in malloc ist, das ist sicher ein Fehler bei dir.
    Du kannst es vielleicht eingrenzen, indem du zuerst irgendwo schreibst if (wert == ...) oder etwas ähnliches, damit du einen Breakpoint setzen kannst, wenn der falsche Wert geschrieben wird.

    Natürlich liegt der Fehler bei mir. Ich habe nie etwas anderes behauptet. Aber ich habe das Gefühl, dass ich diesen Fehler total wo anders begehe. Das Programm stürzt ja nicht ab, sonder läuft durch. Und dieser eine einzige Wert verändert sich während des Programmablaufs.



  • CJens schrieb:

    Ja, deshalb sollte man den Text immer mit Strg+C kopieren. Der Fehler lag in meinem Post, nicht im Code.

    Wie soll dir jemand helfen, wenn du noch nicht mal den fraglichen Code richtig postest?

    Schalte VS auf C Code um oder benenne die Dateien in *.c statt *.cpp.
    VS hat Intellisense, nutze das.
    FB->FBox[i].npFace muss den richtigen (d.h. überlicherweise einen höheren) Wert haben als der Ursprungsspeicherbereich.
    realloc macht keine Fehler, das Debuggen von realloc würde dir nicht helfen.
    Der Fehler sitzt vor dem Monitor und nicht im Compiler.



  • Wutz schrieb:

    Schalte VS auf C Code um oder benenne die Dateien in *.c statt *.cpp.

    Dann funktioniert extern "C" __declspec(dllexport) ... nicht mehr

    Wutz schrieb:

    FB->FBox[i].npFace muss den richtigen (d.h. überlicherweise einen höheren) Wert haben als der Ursprungsspeicherbereich.

    Das ist gegeben, weil die Menge aus der ursprünglichen Menge stammt.

    Wutz schrieb:

    realloc macht keine Fehler, das Debuggen von realloc würde dir nicht helfen.
    Der Fehler sitzt vor dem Monitor und nicht im Compiler.

    Hab nie was anderes behauptet.



  • In C brauchst du auch kein extern "C", ist ja schließlich schon C.



  • Techel schrieb:

    In C brauchst du auch kein extern "C", ist ja schließlich schon C.

    Gelöst hat es das Problem leider nicht, habe das gemacht. Da hat mir der Compiler noch ein paar Sachen angezeigt. Die habe ich behoben. Das Problem besteht aber weiterhin.

    Also, Dateiendung ist jetzt *.c und alle extern "C" __declspec sind in extern __declspec abgeändert.



  • Wutz schrieb:

    Der Fehler sitzt vor dem Monitor und nicht im Compiler.

    Haha, der Fehler sitzt vor dem Monitor und nicht dahinter.



  • Ok, ich denke wir haben jetzt geklärt, dass malloc und realloc korrekt arbeiten. Ich habe das auch nie anders behauptet. Auch, dass der Fehler vor dem Monitor sitzt wurde ausführlich diskutiert. Das hat mir aber erstmal nicht wirklich weiter geholfen.

    Das Problem ist, dass durch ein malloc oder ein realloc ein komplett unabhängiger Wert überschrieben wird. Das kann ich kontrollieren, indem ich den Wert direkt vor dem malloc oder realloc und direkt danach durch ein printf ausgebe. Vielleicht verursacht auch das printf die Änderung, das weiß ich nicht. Und vor diesem Codeabschnitt laufen schon viele Seiten Code. Und da habe ICH wohl irgendwo einen Fehler gemacht. Und ich möchte einen Ratschlag, wie ich mich zu diesem Fehler hin arbeiten kann, denn ich habe keine Ahnung, wo das sein kann.

    Die Funktion selbst, in welcher der Codeabschnitt vorkommt, ist Teil einer räumlichen Octree-Zerlegung und läuft bei anderen Eingabedateien wunderbar. Die wird im Laufe des Codes mehrere tausend mal ausgeführt.

    printf("\t\tPre[%i]: N[359].Gamma[3]: %2.4e\n", i, N[359].Gamma[3]);/*Liefert "Pre[3]: N[359].Gamma[3] = 0.25e000"*/
    FB->FBox[i].F_Thread = (TFace**)realloc(FB->FBox[i].F_Thread, FB->FBox[i].npFace * sizeof(TFace*));
    printf("\t\tPost[%i]: N[359].Gamma[3]: %2.4e\n", i, N[359].Gamma[3]); /*Liefert z.B."Post[3]: N[359].Gamma[3] = 1.91e-208"*/
    

    N[359] ist der Knoten mit dem Index 359 - wie anfangs beschrieben, wird hier an einem 3D Gitter gearbeitet. Der wird in dieser Funktion eigentlich gar nicht bearbeitet, sondern wird statisch im Speicher gehalten. Die Funktion hier arbeitet an etwas komplett anderem. Ich konnte einfach durch Eingrenzen feststellen, dass der Wert an diesem Knoten im statischen Speicher an dieser Stelle verändert wird.



  • dass der Wert an diesem Knoten im statischen Speicher an dieser Stelle verändert wird.

    an welcher Stelle - bei den printfs? da wird doch gar nichts veraendert?
    ausser F_Thread durch das realloc

    Fragen/Tips:
    1. könnte es ein Threading-Problem sein - also konkurrierende Zugriffe oder sowas?

    2. auf welchem Kompiler/OS läuft dein C/C++ Backend? falls Linux(nur x64) mit gcc/clang geht könntest du mal den Address- und Thread-Sanitizer drauf los lassen - und damit schnell eine riesen Horde Fehler ausschliessen (die beiden Tools sind absolut Gold wert, Danke google)

    3. du solltest zur besseren Fehlereingrenzung von deinem C#-GUI wegkommen und direkt den C/C++ Code Debuggen - also einfach die DllMain durch eine echte/hartkodierte main mit deinem Test ersetzen- und die Dll als Executable kompilieren - dann hast du garantiert keine Debugging-Probleme mehr - ausserdem ist C# für die Fehlereingrenzung nicht relevant und stört nur - oder ist der Auslöser (aber das merkst du dann sehr schnell)

    4. den Test in Release wie auch in Debug laufen lassen - gibts Unterschiede?

    5. Aufräumen und solche ausgeschriebenen Vorkommen von "FB->FBox[i]..." durch lokale Referenz/Pointer ersetzen - schon zu oft ein falsches Einstechen bei so [x][y][z] Einstech-Orgien gesehen

    for (i = 0; i < 8/*Magic Value*/; i++)
    { 
      /*auto&*/ curr_fbox = FB->FBox[i];
      /*auto&*/ n_359_gamma3 = N[359].Gamma[3]; // falls wirklich wie eine Art Konstante genutzt
    
      printf("n_359_gamma3 = %2.4e\n", n_359_gamma3); /*Liefert 0.2500e000*/ 
      curr_fbox.F_Thread = (TFace**)realloc(curr_fbox.F_Thread, curr_fbox.npFace * sizeof(TFace*)); /*Hier wird der Wert überschrieben*/ 
      printf("n_359_gamma3 = %2.4e\n", n_359_gamma3); /*Liefert 9.12e-008*/ 
      if (curr_fbox.F_Thread == NULL){ printf("ERROR - Unable to allocate memory!\n"); getchar(); return 1; } 
      curr_fbox.npFace = 0;
      ...
    }
    


  • Hier der Original-Code. Eine Menge an Flächen, wird anhand des Ortsvektors ihres Zentrums F->P.vx unterteilt. Nur zur Bildschirmausgabe wird das Gitter in Form der Struktur TMesh übergeben - wird NULL übergeben, erfolgt keine Bildschirmausgaben, da OutputLoc = 0. pNode ist die Menge von Knoten. Bei Knoten 359 tritt die Änderung auf.

    typedef struct TNode{
    	TPoint P;
    
    	struct TCell** EP;
    	double* Gamma;
    	unsigned int nEP;
    	struct TFace** FP;
    	unsigned int nFP;
    
    	unsigned long Index;
    	unsigned long Index2;
    	unsigned int Internal;
    }TNode;
    
    typedef struct TFace{
    	struct TPoint P;
    	struct TNode** ppNode;
    	struct TVector Normal;
    	struct TVector e;
    	struct TCell* E[2];
    
    	double Area;
    	double fP;
    	double MassFlow;
    	double MassFlow0;
    
    	double JacobiMatrix[3][3];
    	double TransformMatrix[3][3];
    	double JacobiDeterminante;
    	TNode* SecondJacobiNode;
    
    	unsigned int nNode;
    	unsigned long Index;
    	unsigned long Index2;
    	TVector vf;
    	TVector vf0;
    
    	struct TFamily* pFamily;
    }TFace;
    
    typedef struct FBBox{
    	TFace** F_Thread;
    	unsigned long npFace;
    
    	struct FBBox* FBox;
    
    	double XMin, XAve, XMax;
    	double YMin, YAve, YMax;
    	double ZMin, ZAve, ZMax;
    }FBBox;
    int SubdivideOneFBox(FBBox* FB, TMesh* M){
    #pragma region LocalVariables
    	unsigned long i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, OutputLoc = 0;
    	TFace* F = NULL;
    	TFace** Dummy = NULL;
    #pragma endregion LocalVariables
    
    	if (FB->npFace <= 10){
    		return 0;
    	}
    
    	if (M != NULL) { OutputLoc = 1; }
    
    	FB->FBox = malloc(8 * sizeof(FBBox));
    	if (FB->FBox == NULL){ printf("ERROR - Unable to allocate memory!\n"); getchar(); return 1; }
    
    	for (i = 0; i < 8; i++){ 
    		FB->FBox[i].F_Thread = malloc(FB->npFace * sizeof(TFace*)); 
    		if (FB->FBox[i].F_Thread == NULL){ printf("ERROR - Unable to allocate memory!\n"); getchar(); return 1; }
    		FB->FBox[i].npFace = 0;
    	}
    
    	for (i = 0; i < FB->npFace; i++){
    		F = FB->F_Thread[i];
    
    		if (F->P.vx[0] > FB->XAve){ /*Box1, Box2, Box3, Box4*/
    			if (F->P.vx[1] > FB->YAve){ /*Box1, Box2*/
    				if (F->P.vx[2] > FB->ZAve){ /*Box1*/
    					FB->FBox[0].F_Thread[FB->FBox[0].npFace++] = F;
    				} else{ /*Box2*/
    					FB->FBox[1].F_Thread[FB->FBox[1].npFace++] = F;
    				}
    			} else{ /*Box3, Box4*/
    				if (F->P.vx[2] > FB->ZAve){ /*Box3*/
    					FB->FBox[2].F_Thread[FB->FBox[2].npFace++] = F;
    				}
    				else{ /*Box4*/
    					FB->FBox[3].F_Thread[FB->FBox[3].npFace++] = F;
    				}
    			}
    		}else{/*Box5, Box6, Box7, Box8*/
    			if (F->P.vx[1] > FB->YAve){ /*Box5, Box6*/
    				if (F->P.vx[2] > FB->ZAve){ /*Box5*/
    					FB->FBox[4].F_Thread[FB->FBox[4].npFace++] = F;
    				}else{ /*Box6*/
    					FB->FBox[5].F_Thread[FB->FBox[5].npFace++] = F;
    				}
    			}else{ /*Box7, Box8*/
    				if (F->P.vx[2] > FB->ZAve){ /*Box7*/
    					FB->FBox[6].F_Thread[FB->FBox[6].npFace++] = F;
    				} else{ /*Box8*/
    					FB->FBox[7].F_Thread[FB->FBox[7].npFace++] = F;
    				}
    			}
    		}
    	}
    
    	for (i = 0; i < 8; i++) {
    
    		if (OutputLoc == 1) { printf("\t\tPre[%i]: N[359].Gamma[3] = %2.4e\n", i, M->pNode[359].Gamma[3]);}
    		FB->FBox[i].F_Thread = (TFace**)realloc(FB->FBox[i].F_Thread, FB->FBox[i].npFace * sizeof(TFace*));
    		if (OutputLoc == 1) {printf("\t\tPost[%i]: N[359].Gamma[3] = %2.4e\n", i, M->pNode[359].Gamma[3]);}
    
    		switch (i){
    			case 0: /*Box 1*/
    				FB->FBox[i].XMin = FB->XAve;
    				FB->FBox[i].XMax = FB->XMax;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YAve;
    				FB->FBox[i].YMax = FB->YMax;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZAve;
    				FB->FBox[i].ZMax = FB->ZMax;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    			case 1: /*Box 2*/
    				FB->FBox[i].XMin = FB->XAve;
    				FB->FBox[i].XMax = FB->XMax;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YAve;
    				FB->FBox[i].YMax = FB->YMax;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZMin;
    				FB->FBox[i].ZMax = FB->ZAve;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    			case 2: /*Box 3*/
    				FB->FBox[i].XMin = FB->XAve;
    				FB->FBox[i].XMax = FB->XMax;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YMin;
    				FB->FBox[i].YMax = FB->YAve;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZAve;
    				FB->FBox[i].ZMax = FB->ZMax;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    
    				break;
    			case 3: /*Box 4*/
    				FB->FBox[i].XMin = FB->XAve;
    				FB->FBox[i].XMax = FB->XMax;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YMin;
    				FB->FBox[i].YMax = FB->YAve;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZMin;
    				FB->FBox[i].ZMax = FB->ZAve;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    			case 4: /*Box 5*/
    				FB->FBox[i].XMin = FB->XMin;
    				FB->FBox[i].XMax = FB->XAve;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YAve;
    				FB->FBox[i].YMax = FB->YMax;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZAve;
    				FB->FBox[i].ZMax = FB->ZMax;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    			case 5: /*Box 6*/
    				FB->FBox[i].XMin = FB->XMin;
    				FB->FBox[i].XMax = FB->XAve;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YAve;
    				FB->FBox[i].YMax = FB->YMax;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZMin;
    				FB->FBox[i].ZMax = FB->ZAve;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    			case 6: /*Box 7*/
    				FB->FBox[i].XMin = FB->XMin;
    				FB->FBox[i].XMax = FB->XAve;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YMin;
    				FB->FBox[i].YMax = FB->YAve;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZAve;
    				FB->FBox[i].ZMax = FB->ZMax;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    			default: /*Box 8*/
    				FB->FBox[i].XMin = FB->XMin;
    				FB->FBox[i].XMax = FB->XAve;
    				FB->FBox[i].XAve = .5 * (FB->FBox[i].XMax + FB->FBox[i].XMin);
    
    				FB->FBox[i].YMin = FB->YMin;
    				FB->FBox[i].YMax = FB->YAve;
    				FB->FBox[i].YAve = .5 * (FB->FBox[i].YMax + FB->FBox[i].YMin);
    
    				FB->FBox[i].ZMin = FB->ZMin;
    				FB->FBox[i].ZMax = FB->ZAve;
    				FB->FBox[i].ZAve = .5 * (FB->FBox[i].ZMax + FB->FBox[i].ZMin);
    				break;
    		}
    	}
    
    	free(FB->F_Thread);
    	//FB->npFace = 0;
    
    	return 0;
    }
    


  • ist es gewollt das in case 0: das break fehlt?

    case 0: /*Box 1*/ 
                    fbox.XMin = FB->XAve; 
                    fbox.XMax = FB->XMax; 
                    fbox.XAve = .5 * (fbox.XMax + fbox.XMin); 
    
                    fbox.YMin = FB->YAve; 
                    fbox.YMax = FB->YMax; 
                    fbox.YAve = .5 * (fbox.YMax + fbox.YMin); 
    
                    fbox.ZMin = FB->ZAve; 
                    fbox.ZMax = FB->ZMax; 
                    fbox.ZAve = .5 * (fbox.ZMax + fbox.ZMin); 
                case 1: /*Box 2*/ 
                    fbox.XMin = FB->XAve; 
                    fbox.XMax = FB->XMax; 
                    fbox.XAve = .5 * (fbox.XMax + fbox.XMin); 
    
                    fbox.YMin = FB->YAve; 
                    fbox.YMax = FB->YMax; 
                    fbox.YAve = .5 * (fbox.YMax + fbox.YMin); 
    
                    fbox.ZMin = FB->ZMin; 
                    fbox.ZMax = FB->ZAve; 
                    fbox.ZAve = .5 * (fbox.ZMax + fbox.ZMin); 
                    break;
    


  • und räum mal auf

    fbox.XMin = FB->XAve; 
                    fbox.XMax = FB->XMax; 
                    fbox.XAve = .5 * (fbox.XMax + fbox.XMin); 
    
                    fbox.YMin = FB->YAve; 
                    fbox.YMax = FB->YMax; 
                    fbox.YAve = .5 * (fbox.YMax + fbox.YMin); 
    
                    fbox.ZMin = FB->ZAve; 
                    fbox.ZMax = FB->ZMax; 
                    fbox.ZAve = .5 * (fbox.ZMax + fbox.ZMin);
    
    set_fbox_xyz(FBox*, XMin, XMax, XAve, YMin, YMax, YAve, ...)
    
    set_fbox_xyz
    (
     fbox, 
     FB->XAve, FB->XMax, .5 * (fbox.XMax + fbox.XMin, 
     FB->YAve, FB->YMax, .5 * (fbox.YMax + fbox.YMin),
     FB->ZAve, FB->ZMax, .5 * (fbox.ZMax + fbox.ZMin),
    );
    

    macht daraus viele Einzeiler - und dann kann man leichter Fehler finden



  • Gast3 schrieb:

    dass der Wert an diesem Knoten im statischen Speicher an dieser Stelle verändert wird.

    an welcher Stelle - bei den printfs? da wird doch gar nichts veraendert?
    ausser F_Thread durch das realloc

    Das ist es ja. Der Knotenwert wird nicht mal an die Funktion übergeben. Ich mache das hier nur, um den Wert überwachen zu können.

    Gast3 schrieb:

    Fragen/Tips:
    1. könnte es ein Threading-Problem sein - also konkurrierende Zugriffe oder sowas?

    Nein. Ich Nutze zwar Threading, hab das dann aber zu Testzwecken deaktiviert und führe die Funktion direkt im Code aus.

    Gast3 schrieb:

    2. auf welchem Kompiler/OS läuft dein C/C++ Backend? falls Linux(nur x64) mit gcc/clang geht könntest du mal den Address- und Thread-Sanitizer drauf los lassen - und damit schnell eine riesen Horde Fehler ausschliessen (die beiden Tools sind absolut Gold wert, Danke google)

    Beides Visual Studio 2015 - Windows 7 64 Bit. Hab als platform x64 gewählt.

    Gast3 schrieb:

    3. du solltest zur besseren Fehlereingrenzung von deinem C#-GUI wegkommen und direkt den C/C++ Code Debuggen - also einfach die DllMain durch eine echte/hartkodierte main mit deinem Test ersetzen- und die Dll als Executable kompilieren - dann hast du garantiert keine Debugging-Probleme mehr - ausserdem ist C# für die Fehlereingrenzung nicht relevant und stört nur - oder ist der Auslöser (aber das merkst du dann sehr schnell)

    Langfristig, gerne. Aber ich habe mich mit QT noch nicht auseinandergesetzt und das Programm ist schon sehr weit fortgeschritten:
    https://www.youtube.com/watch?v=iCjezalOBP4

    Muss das jetzt so erstmal fertig bringen...
    Außerdem wurde mir hier im Forum gesagt: "Nutze nie C/C++ um GUIs zu
    programmieren!!" 😋

    Gast3 schrieb:

    4. den Test in Release wie auch in Debug laufen lassen - gibts Unterschiede?

    Kein Unterschied...

    Gast3 schrieb:

    5. Aufräumen und solche ausgeschriebenen Vorkommen von "FB->FBox[i]..." durch lokale Referenz/Pointer ersetzen - schon zu oft ein falsches Einstechen bei so [x][y][z] Einstech-Orgien gesehen

    for (i = 0; i < 8/*Magic Value*/; i++)
    { 
      /*auto&*/ curr_fbox = FB->FBox[i];
      /*auto&*/ n_359_gamma3 = N[359].Gamma[3]; // falls wirklich wie eine Art Konstante genutzt
    
      printf("n_359_gamma3 = %2.4e\n", n_359_gamma3); /*Liefert 0.2500e000*/ 
      curr_fbox.F_Thread = (TFace**)realloc(curr_fbox.F_Thread, curr_fbox.npFace * sizeof(TFace*)); /*Hier wird der Wert überschrieben*/ 
      printf("n_359_gamma3 = %2.4e\n", n_359_gamma3); /*Liefert 9.12e-008*/ 
      if (curr_fbox.F_Thread == NULL){ printf("ERROR - Unable to allocate memory!\n"); getchar(); return 1; } 
      curr_fbox.npFace = 0;
      ...
    }
    

    Schwierig, denn genau darin liegt die Systematik, wenn ich eine Menge in genau acht Untermengen räumlich unterteilen möchte. Außerdem funktioniert die Routine so. Ich habe sie häufig eingesetzt und sie hat stets das richtige geliefert.



  • Gast3 schrieb:

    ist es gewollt das in case 0: das break fehlt?

    case 0: /*Box 1*/ 
                    fbox.XMin = FB->XAve; 
                    fbox.XMax = FB->XMax; 
                    fbox.XAve = .5 * (fbox.XMax + fbox.XMin); 
      
                    fbox.YMin = FB->YAve; 
                    fbox.YMax = FB->YMax; 
                    fbox.YAve = .5 * (fbox.YMax + fbox.YMin); 
      
                    fbox.ZMin = FB->ZAve; 
                    fbox.ZMax = FB->ZMax; 
                    fbox.ZAve = .5 * (fbox.ZMax + fbox.ZMin); 
                case 1: /*Box 2*/ 
                    fbox.XMin = FB->XAve; 
                    fbox.XMax = FB->XMax; 
                    fbox.XAve = .5 * (fbox.XMax + fbox.XMin); 
      
                    fbox.YMin = FB->YAve; 
                    fbox.YMax = FB->YMax; 
                    fbox.YAve = .5 * (fbox.YMax + fbox.YMin); 
      
                    fbox.ZMin = FB->ZMin; 
                    fbox.ZMax = FB->ZAve; 
                    fbox.ZAve = .5 * (fbox.ZMax + fbox.ZMin); 
                    break;
    

    Danke für den Hinweis. Wieso hat das nichts ausgelöst? Hab es korrigiert, der Fehler besteht aber weiterhin.



  • Lass dir nicht alles einzeln aus der Nase ziehen,
    gib die Definition von N und aller beteiligten Typen konkret an (ohne Abschreib-Fehler).


Log in to reply