Funktion steigt vor return aus
-
Ich habe eine Function geschrieben, die auch korrekt arbeitet. Allerdings hängt sich dann das Programm auf.
Die Funktion im Original:
int CalcTriSpecification(TElement* P){ unsigned long fi=0, fj=0, fk=0, fl=0; double DummyX=.0; double DummyY=.0; double DP=.0; TPoint* fP2=NULL,* fP1=NULL; TNode *DummyNode=NULL; TVector VOPN1, VP1, VP0; //Center of element printf("Calculating element center\n"); for (fi=0; fi<3;fi++){ DummyX+=P->Node[fi]->P.x; DummyY+=P->Node[fi]->P.y; } P->P.x = DummyX/3.; P->P.y = DummyY/3.; printf("Element center at (%2.4f/%2.4f)\n", P->P.x, P->P.y); //Alligning nodes leftsided printf("Alligning nodes lefthanded\n"); //Vector form element center to Node[0] VP0 = VectorP(&P->Node[0]->P, &P->P); NormalizeVector(&VP0); //Orthogonal vector from element center to Node[0] VOPN1 = OrthogonalPV(&VP0); fj=0; fk=1; /*vector from center to the ith node*/ VP1 = VectorP(&P->Node[1]->P, &P->P); /*generating normal vector of ith vector*/ NormalizeVector(&VP1); if(DotProductV(&VOPN1,&VP1)<0.0){ DummyNode = P->Node[1]; P->Node[2]=P->Node[1]; P->Node[2]=DummyNode; } for(fi=0;fi<3;fi++){printf("Node[%lu].ExternalNumber: %lu\n", fi, P->Node[fi]->ExternalNumber);} printf("Calculating normal vector, side length and area\n"); //Calculate normal vector, side length and area P->Se = (double*)calloc(3, sizeof(double)); P->Normal = (TVector*)calloc(3, sizeof(TVector)); printf("Memory allocated\n"); fP2 = &P->Node[0]->P; fP1 = &P->Node[2]->P; OrthogonalNP2(fP2, fP1, &P->Normal[2]); NormalizeVector(&P->Normal[2]); P->Se[2] = PointDistance(fP2, fP1); P->Area=AreaTriangle(&P->P, fP1, fP2); for (fi=0; fi<2;fi++){ fP2 = &P->Node[fi+1]->P; fP1 = &P->Node[fi]->P; OrthogonalNP2(fP2, fP1, &P->Normal[fi]); NormalizeVector(&P->Normal[fi]); P->Se[fi] = PointDistance(fP2, fP1); } for(fi=0;fi<3;fi++){printf("Side[%lu]:\n\tNormal[%lu]: (%2.4f/%2.4f)\n\tSideLength[%lu]: %2.4f\n\n", fi, fi, P->Normal[fi].vx, P->Normal[fi].vy, fi, P->Se[fi]);} printf("Finished\n"); return 0; }
Die Funktion berechnet die Spezifikationen eines Dreiecks (Fläche, Normalenvektoren der Kanten, Schwerpunkt etc.) und wird in einer weiteren Funktion aufgerufen. Es gibt also noch analoge Functions für Vierecke, Balkenelemente und Polygone... der Fehler tritt aber bei dem ersten Element auf - und das ist ein Dreieck...
int CalculateElementSpecification(TDomain* D){ unsigned long fi=0, fj=0; TElement* fpElement = D->pElement; unsigned long* DummyNumber=(unsigned long*)calloc(1000, sizeof(unsigned long)); double* DummyDOTP=(double*)calloc(1000, sizeof(double)); for(fi=0;fi<D->nElement;fi++){ printf("fi = %lu\n", fi); if(fpElement[fi].nNode==2){ CalcBarSpecification(&fpElement[fi]); //Bar element printf("Successfull!\n\n"); }else if(fpElement[fi].nNode==3){ fj = CalcTriSpecification(&fpElement[fi]); //Triangle element printf("Successfull! &lu\n\n", fj); }else if(fpElement[fi].nNode==4){ CalcQuadSpecification(&fpElement[fi], DummyNumber, DummyDOTP); //Quad element printf("Successfull!\n\n"); }else if(fpElement[fi].nNode>4){ CalcPolySpecification(&fpElement[fi], DummyNumber, DummyDOTP); //Polygon element printf("Successfull!\n\n"); } printf("Next round\n"); } free(DummyNumber); free(DummyDOTP); return 0; }
Am Bildschirm wird alles korrekt ausgegeben. Die letzte Ausgabe ist Finished, welches ja über das printf in der Function CalcTriSpecification vor der return 0 Anweisung ausgegeben wird. Die printf Anweisung "Successfull!" wird aber nicht mehr ausgegeben. Das bedeutet, die Funktion steigt irgendwo zwischen dem printf("Finished!\n") und dem printf("Successfull!\n\n") aus.
Wenn das Programm aussteigt, kommt "Programmname.exe funktioniert nicht mehr. Es wird nach einer Lösung für das Problem gesucht..."
Nochmal, die berechneten Ausgaben für die Vektoren, die Knoten, Fläche und Seitenlängen sind alle korrekt - die Routine funktioniert also eigentlich.
Hat jemand ne Idee?
Der Vollständigkeit halber anbei die Structs:
typedef struct { double x; double y; double z; } TPoint; typedef struct { double vx; double vy; } TVector; typedef struct{ unsigned int Number; char* Name; }TFamily; typedef struct { //Coordinates of node TPoint P; //Index and external number of current node unsigned long ExternalNumber; unsigned long Index; //Number of connected elements unsigned int nEP; //Internal node char Internal; //Interpolation coefficient double *Gamma; //Connected elements void **EP; } TNode; typedef struct{ //Center TPoint P; //Element number unsigned long ExternalNumber; unsigned long Index; //Number of nodes unsigned int nNode; TNode** Node; //Flux connected elements void** E; //Area double Area; //Normal vector TVector *Normal; //Sidelength double *Se; //Internal element char Internal; //Family unsigned int Family; }TElement; typedef struct{ TNode** Node; //Sidelength double Se; //Normal vector TVector *Normal; //External element number unsigned long ExternalNumber; //Internal index unsigned long index; //Family of element unsigned int Family; }TBar;
Und die Functions für die Vektorberechnung:
TVector OrthogonalPV(TVector* v){ TVector VO; VO.vx = -v->vy; VO.vy = v->vx; return VO; } void OrthogonalNP2(TPoint* P2, TPoint* P1, TVector* VO){ VO->vx = P2->y - P1->y; VO->vy = P1->x - P2->x; } void NormalizeVector(TVector* V){ double l = Vektorlength(V); V->vx/=l; V->vy/=l; } double Vektorlength(TVector* V){return sqrt(V->vx*V->vx + V->vy*V->vy);}
-
Wahrscheinlich hast du dann deinen Stack zerschossen, wo die Rücksprungadresse der Funktion abgelegt ist.
Hast du denn keinen Debugger, um das Programm im Einzelschritt durchzugehen und die Variablenwerte anzuschauen?
-
Du überschreibst wohl irgendwie aufgrund falscher Pointer die return-Addresse deiner Funktion, d.h. die springt dann irgendwo hin, wenn sie fertig ist.
Ist vermutlich ein Array-Bounds-Verletzung. Bin zu faul, das jetzt im Detail durchzugehen, probiers mal mit einem Debugger.
-
...werde das überprüfen - aber wie kann ich auf die Rücksprungadresse der Function zugreifen.
Arbeite eigentlich mit Texteditor und TCC Compiler - aber hab auch VCpp 2013 installiert, für den Fall, dass ich mal garnicht weiter komme und nen Debugger benötige.
-
CJens schrieb:
...werde das überprüfen - aber wie kann ich auf die Rücksprungadresse der Function zugreifen.