提问人:K. Russell Smith 提问时间:6/26/2020 最后编辑:K. Russell Smith 更新时间:6/26/2020 访问量:82
C物理程序中的不规则行为
Irregular behavior in C physics program
问:
我正在尝试将一个简单的物理引擎组合在一起:
#include <stdio.h>
typedef struct Vector
{
double x, y;
} Vector;
const double GRAVITY = 0.1;
const double FRICTION = 0.9;
typedef struct RigidBody
{
Vector* pos;
Vector* vel;
Vector* acc;
uint16_t mass;
} RigidBody;
void addForce(RigidBody* body, double x, double y)
{
body->acc->x += x / body->mass;
body->acc->y += y / body->mass;
}
void updateRigidBody(RigidBody* body)
{
addForce(body, 0, GRAVITY * body->mass);
body->vel->x += body->acc->x;
body->vel->y += body->acc->y;
body->vel->x *= FRICTION;
body->vel->y *= FRICTION;
body->pos->x += body->vel->x;
body->pos->y += body->vel->y;
body->acc->x = 0;
body->acc->y = 0;
}
void resetRigidBody(RigidBody* body, double x, double y)
{
body->pos->x = x;
body->pos->y = y;
body->vel->x = 0;
body->vel->y = 0;
body->acc->x = 0;
body->acc->y = 0;
}
struct
{
RigidBody body;
} Player;
void initPlayer(double x, double y)
{
Player.body = (RigidBody)
{
&((Vector) {x, y}),
&((Vector) {0, 0}),
&((Vector) {0, 0}),
10,
};
}
void updatePlayer()
{
updateRigidBody(&Player.body);
}
void resetPlayer(double x, double y)
{
resetRigidBody(&Player.body, x, y);
}
int main()
{
initPlayer(10, 10);
{
int i;
for (i = 0; i < 10; ++i)
{
updatePlayer();
}
}
printf("%g", Player.body.pos->y);
return 0;
}
不幸的是,它不会打印预期的结果,而是打印 0.99。我试图通过在更新刚体后打印刚体的 Y 速度来诊断它,方法是在第 42 行之后添加以下内容:
printf("%g\n", body->vel->y);
不幸的是,这实际上改变了结果:
0.99
0.99
0.99
0.99
0.99
0.99
0.99
0.99
0.99
0.99
4.16586e-312
这似乎表明内存问题可能是由未定义的行为引起的,但从我的代码来看,一切似乎都很正常,我的编译器没有发出任何警告;我还避免分配任何内存(例如使用 malloc),而是依赖堆栈。我的代码有什么问题?谢谢。
答:
3赞
M.M
6/26/2020
#1
在此代码中:
Player.body = (RigidBody)
{
&((Vector) {x, y}),
&((Vector) {0, 0}),
&((Vector) {0, 0}),
10,
};
块范围内有复合文字,这意味着它们的生存期在当前块之后结束。当函数返回时,该对象包含悬空指针。body
不使用指针会简单得多:
typedef struct RigidBody
{
Vector pos, vel, acc;
uint16_t mass;
} RigidBody;
// ...
Player.body = (RigidBody)
{
.pos.x = x,
.pos.y = y,
.mass = 10
};
评论
Player.body
InitPlayer()