簡體   English   中英

Segfault,在ANSI C代碼中具有指向char的指針

[英]Segfault with pointer to char inside struct, ANSI C code

以下簡單的ANSI C代碼出現奇怪的行為。 我在結構中有一個指向char的指針,以某種方式,我有錯誤的指針,空值和段錯誤。 我在做蠢事嗎?

#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;
}

game_init ,您要聲明一個scene_t類型的局部變量。 一旦game_init結束, 該變量將不再存在 -您無法在該函數之外正確使用它,但這是您訪問game_t變量內的場景時要嘗試的操作。

如果要創建一個可以在函數外部使用的scene_t,則需要使用手動為其分配內存。

scene_t* scene = malloc(sizeof(scene_t));

...然后將其用作指針。

您正在保存一個本地地址,當功能超出范圍時,“場景”將被破壞。

scene_t scene;

memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;

您應該分配場景

scene_t* scene = malloc(sizeof(scene_t)); 

問題是您沒有分配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此內存。

創建新的幻影時,也不會為scene->appearance分配值。 當您稍后嘗試打印外觀時,您將得到指針碰巧指向已打印ou的所有內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM