SOLVED: Brauche einen Rat beim Debuggen...



  • 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).



  • Wutz schrieb:

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

    Hab den Code ergänzt.



  • Hast du bei malloc/realloc auch immer das richtige sizeof benutzt?

    Nutze den dereferenzierten Zeiger für sizeof

    int *p;
    
    p = malloc(1000*sizeof(int))   // schlecht, da du wissen muss, was p ist.
    p = malloc(1000*sizeof(*p))    // besser 
    p = malloc(1000*sizeof(p[0]))  // geht auch
    

    Gerade bei deinen vielen structs besteht leicht die Möglichkeit, dass du das bei copy&paste mal vergessen hast.

    Dein N oder M kann ja schon von der Größe falsch sein.
    Hat sich evtl. schon M oder pNode oder Gamma verändert (irgendein Zeger auf dem Weg zu Gamma[3]?
    Hat Gamma überhaupt min. 4 Elemente?

    Benutzt du VLA oder Rekursion (reicht dein Stack)?



  • int SubdivideOneFBox(FBBox* FB, TMesh* M){
    

    - Definition von TMesh fehlt

    M zeigt ja wohl irgendwie auf FB, wenn du also durch realloc den FB-Speicherbereich verschiebst (und die Größe änderst), wie stellst du dann sicher, dass M davon was mitbekommt?
    Ich sehe auch kein free zu deinem realloc.



  • 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!!" 😋

    das meinte ich nicht - du sollst nur für die Fehlereingrenzung das GUI Verlassen und die Dll (kurz mal) in eine Applikation umwandeln und dort deinen Test machen - dann wäre klar ob es an C# oder C/C++ liegt (es ist für niemanden hier klar wie C# die Schnittstelle nutzt), und dein Debugger funktioniert anständig



  • 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.

    du sollst ja auch nur aufräumen - nicht die Semantik verändern

    1. hättest du dann eher das fehlende break gesehen und 2. passieren dann Indizierungsfehler viel seltener



  • noch ein Tip:

    das Fehler-Szenario so schnell wie möglich reduzieren

    -bleib in C/C++ mit deinen Tests - lass C# erstmal raus

    -mind 2. Testszenarien hart im Code - ein funktionierendes 1 falsches
    z.B. nur in der Dll eine Textdatei oder sonstige Datengrundlage laden und durchjagen - Fehler reproduzieren

    ich würde mir z.B. einfach eine init oder sonstige Routine in der Dll suchen und dort hart eine test_fehler() routinen einbauen die mir die Daten laed und die SubdivideOneFBox aufruft, wenn der dort nicht auftritt liegt der Fehler einfach irgendwo anders

    schnell und einfach


Anmelden zum Antworten