我对以下简单的ANSI C代码有一种奇怪的行为。我有一个指向结构中的字符的指针,不知何故,我有坏指针,空值和段错误。我做了些蠢事吗?
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_ENTITIES 10
typedef enum
{
COMPONENT_NONE = 0,
COMPONENT_DISPLACEMENT = 1 << 0,
COMPONENT_VELOCITY = 1 << 1,
COMPONENT_APPEARANCE = 1 << 2
} component_t;
typedef struct
{
float x;
float y;
} Displacement;
typedef struct
{
float x;
float y;
} Velocity;
typedef struct
{
char *name;
} Appearance;
typedef struct
{
int entities[MAX_ENTITIES];
Displacement displacement[MAX_ENTITIES];
Velocity velocity[MAX_ENTITIES];
Appearance appearance[MAX_ENTITIES];
} scene_t;
typedef struct
{
int active;
scene_t *current_scene;
} game_t;
unsigned int entity_create(scene_t *scene)
{
unsigned int entity;
for (entity = 0; entity < MAX_ENTITIES; ++entity) {
if (scene->entities[entity] == COMPONENT_NONE) {
printf("Entity created: %u\n", entity);
return entity;
}
}
printf("Error! No more entities left!\n");
return MAX_ENTITIES;
}
unsigned int scene_add_box(scene_t *scene, float x, float y, float vx, float vy)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_VELOCITY | COMPONENT_APPEARANCE;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->velocity[entity].x = vx;
scene->velocity[entity].y = vy;
scene->appearance[entity].name = "Box";
return entity;
}
unsigned int scene_add_tree(scene_t *scene, float x, float y)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_APPEARANCE;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->appearance[entity].name = "Tree";
return entity;
}
unsigned int scene_add_ghost(scene_t *scene, float x, float y, float vx, float vy)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_VELOCITY;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->velocity[entity].x = vx;
scene->velocity[entity].y = vy;
return entity;
}
void update_render(scene_t *scene)
{
const int mask = (COMPONENT_DISPLACEMENT | COMPONENT_APPEARANCE);
unsigned int entity;
Displacement *d;
Appearance *a;
for (entity = 0; entity < MAX_ENTITIES; ++entity) {
if ((scene->entities[entity] & mask) == mask) {
d = &(scene->displacement[entity]);
a = &(scene->appearance[entity]);
printf("%s at (%f, %f)\n", a->name, d->x, d->y);
}
}
}
void game_init(game_t *game)
{
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
game->active = 0;
scene_add_tree(game->current_scene, 5.0f, -3.2f);
scene_add_box(game->current_scene, 0.0f, 0.0f, 0.0f, 0.0f);
scene_add_ghost(game->current_scene, 10.0f, 4.0f, 0.0f, 0.0f);
}
void game_update(game_t *game)
{
update_render(game->current_scene);
}
int main(int argc, char **argv)
{
game_t game;
memset(&game, 0, sizeof(game));
game_init(&game);
while (game.active == 0) {
game_update(&game);
}
return 0;
}
答案 0 :(得分:2)
在game_init
中,您声明了scene_t
类型的局部变量。 game_init
结束后,此变量不再存在 - 您无法在该函数之外正确使用它,但这是您在访问game_t
变量中的场景时尝试执行的操作
如果你想创建一个可以在函数外部使用的scene_t,你需要使用
手动为它分配内存scene_t* scene = malloc(sizeof(scene_t));
...然后将其作为指针使用。
答案 1 :(得分:1)
您正在保存本地地址,当功能超出范围时,“场景”将被销毁。
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
您应该改为分配场景
scene_t* scene = malloc(sizeof(scene_t));
答案 2 :(得分:1)
问题在于您没有分配scene
:
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
此处的scene_t
对象位于堆栈中,一旦退出该函数,该内存将被回收。你应该改为使用
scene_t *pscene = malloc(sizeof(scene_t));
memset(pscene, 0, sizeof(scene));
game->current_scene = pscene;
这样,内存将从堆中分配,从函数退出中幸存下来。
一旦完成对象,您将需要稍后free
这个记忆。
答案 3 :(得分:1)
创建新鬼时,您也不会为scene->appearance
指定值。然后,当您尝试打印外观后,您将获得指向打印的任何指针。