Zeiger auf Zeiger?
-
Hallo,
habe folgendes Problem:
Ich habe in ein Array aus Strukturen dynamisch angelegt:
BallData_t *ballArr = new BallData_t [BallNum] (BallNum ist die Anzahl der Bälle)
nun möchte ich später mit einem anderen Zeiger auf den ersten Eintrag
dieses Arrays verweisen, jedoch zeigt der Zeiger dann immer auf den letzten Eintrag, den ich gemacht habe...
hier mein Code, falls es weiter hilftconst int BallNum = 40; // Zahl N der Baelle const int Rad = 5; // Radius eines Balls const int P_C = 5; // Parameter C der parametrisierten Ballposition const int P_S = 2; // Parameter S der parametrisierten Ballposition const int Dt_Rel = 25; struct BallData_s { double x, y; double t, dt; int vis; }; typedef BallData_s BallData_t; static int width, height; static BallData_t *ballArr; static BallData_t ball; static int bahnRad; static int bahnZentrX, bahnZentrY; void BGEvtInit(void) { BGGetsize(&width, &height); bahnRad = (width>height)? height/3 : width/3; // zweiPi =: bahnRad bahnZentrX = width/2; bahnZentrY = height/2; ballArr = new BallData_t [BallNum+1]; double ballDist = (bahnRad*2) / BallNum; for (int zae = 1; zae <= BallNum; zae++) { ballArr->t = ballDist*zae; ballArr->x = (bahnZentrX+bahnRad*cos(P_C*ballArr->t)); ballArr->y = (bahnZentrY+bahnRad*sin(P_S*ballArr->t)); ballArr->dt = ballArr->t/Dt_Rel; ballArr->vis = false; ballArr++; } } static void ballEvtDraw(BallData_t& ball, int del) { double& x = ball.x; double& y = ball.y; int& vis = ball.vis; if (vis && del) BGCircle((int)x, (int)y, Rad); vis=BGCircle((int)x, (int)y, Rad); } void BGEvtDraw(int del) { BallData_t *pballArr; for (int a = 0; a <= BallNum; a++) { pballArr = &ballArr[a]; <---hier mein Problem! ball.x = pballArr->x; ball.y = pballArr->y; ball.t = pballArr->t; ball.dt = pballArr->dt; ball.vis = pballArr->vis; ballEvtDraw(ball, del); } } void BGEvtExit(void) { free(ballArr); }Kann mir jemand helfen?
-
Wundert dich das wenn du den Schleifenzähler als Index nimmst?
-
Du verwendest den Zeiger um auf die Attribute der Instanzen von den Strukturen zuzugreifen.* Dem Zeiger wird die Adresse des Elements an Position n zugewiesen, wobei der Wert n nach jedem Schleifendurchlauf inkrementiert wird. Bei dem letzten Durchlauf der Schleife zeigt der Zeiger auf das letzte Element des Containers. Anschließend wird der Wert des Zeigers nicht mehr verändert; der Zeiger zeigt weiter auf den letzten Eintrag.
* Warum verwendest du nicht den Operator . zum Zugriff auf die Attribute? ...
struct test { int a; int b; }; test v; v.a = 1; v.b = 2;
-
oder nimm einen lokalen Zeiger in deiner Funktion zum Weiterschalten.
Was soll das hier?typedef BallData_s BallData_t;
-
Deine Schleife darf nur bis BallNum-1
laufen da das Array Werte [0..BallNum-1] Werte hält.
-
Nö,
denn sieheballArr = new BallData_t [BallNum+1];
-
Und noch eine Frage: Wo kommt das free(ballArr) her. Wenn schon, dann passend zum new das delete verwenden, oder passend zum free malloc verwenden. Aber niemals mischen. Und außerdem setzen free und delete voraus, den Zeiger auf das erste Array-Element zu erhalten. Dies ist bei Dir nicht der Fall.
-
ja genau da liegt ja mein problem, wie krieg ich denn den zeiger wieder auf das erste element zurück?
habs jetzt nochmal bissl geändert, es stürzt schonmal nicht mehr ab, aber funktionieren tuts immernoch nich richtig...
struct BallData_s { double x, y; double t, dt; int vis; }; typedef BallData_s BallData_t; static int width, height; static BallData_t *ballArr; static BallData_t ball; static int bahnRad; static int bahnZentrX, bahnZentrY; void BGEvtInit(void) { BGGetsize(&width, &height); bahnRad = (width>height)? height/3 : width/3; bahnZentrX = width/2; bahnZentrY = height/2; ballArr = new BallData_t [BallNum+1]; double ballDist = bahnRad/BallNum; for (int zae=0; zae<=BallNum-1; zae++) { ballArr->t = ballDist*zae; ballArr->x = (bahnZentrX+bahnRad*cos(P_C*ball.t)); ballArr->y = (bahnZentrY+bahnRad*sin(P_S*ball.t)); ballArr->dt = ball.t/Dt_Rel; ballArr->vis = false; ballArr++; } } static void ballEvtDraw(BallData_t& ball, int del) { double& x = ball.x; double& y = ball.y; int& vis = ball.vis; if (vis && del) BGCircle((int)x, (int)y, Rad); ball.x = (bahnZentrX+bahnRad*cos(P_C*ball.t)); ball.y = (bahnZentrY+bahnRad*sin(P_S*ball.t)); ball.t+=ball.dt; vis=BGCircle((int)x, (int)y, Rad); } void BGEvtDraw(int del) { BallData_t *pballArr; int b; for (b=0; b<=BallNum-1; b++) { pballArr = ballArr; ball.x = pballArr->x; ball.y = pballArr->y; ball.t = pballArr->t; ball.dt = pballArr->dt; ball.vis = pballArr->vis; ballEvtDraw(ball, del); } } void BGEvtExit(void) { delete(ballArr); }
-
ja genau da liegt ja mein problem, wie krieg ich denn den zeiger wieder auf das erste element zurück?
Gegenfrage: Warum nimmt du ihn überhaupt vom ersten Element weg? Wenn du durch dein Array iterieren willst, nimm dir eine Kopie des Zeigers und schieb die vorwärts.
-
oder nutze halt den IndexOperator, z.Bsp.
ballArr = new BallData_t [BallNum+1]; double ballDist = bahnRad/BallNum; for (int zae=0; zae<=BallNum; zae++) { ballArr[zae].t = ballDist*zae; ballArr[zae].x = (bahnZentrX+bahnRad*cos(P_C*ball.t)); ballArr[zae].y = (bahnZentrY+bahnRad*sin(P_S*ball.t)); ballArr[zae].dt = ball.t/Dt_Rel; ballArr[zae].vis = false; }