嵌套结构和指针
几乎每次我跳回C项目时,我都会这么说。 在尝试访问结构中的结构时,我遇到了段错误。 假设我有一个游戏的以下(简化)结构:
struct vector { float x; float y; }; struct ship { struct vector *position; }; struct game { struct ship *ship; } game;
以及初始化船舶的function:
static void create_ship(struct ship *ship) { ship = malloc(sizeof(struct ship)); ship->position = malloc(sizeof(struct vector)); ship->position->x = 10.0; }
然后在main()中:
int main() { create_ship(game.ship); printf("%f\n", game.ship->position->x); // <-- SEGFAULT }
您正在按值传递game.ship
,因此在create_ship
,变量ship
是该指针的副本,它只是更改副本。 当函数返回时,除了内存泄漏之外,指向malloc
ed的指针将丢失,并且函数的效果在其外部不可见。
您需要将指针传递给指针并通过game.ship
方式修改game.ship
:
static void create_ship(struct ship **ship) { *ship = malloc(sizeof(struct ship)); (*ship)->position = malloc(sizeof(struct vector)); (*ship)->position->x = 10.0; }
和
create_ship(&game.ship);
或者也许更好的方法是按照Johnny Mopp在评论中建议的那样,从函数返回指针而不是修改它之外的指针:
static struct ship* create_ship() { struct ship* s = malloc(sizeof(struct ship)); s->position = malloc(sizeof(struct vector)); s->position->x = 10.0; return s; }
和
game.ship = create_ship();
当然,你有什么编辑,不要忘记free
。
你应该通过参考传递:
static void create_ship(struct ship **ship);
和
create_ship(&game.ship);
否则分配的结构将被丢弃。
你的create_ship
函数实际上并没有改变game.ship
,因为参数是按值传递的 。 在create_ship
函数中,只更改了一个副本 。 因此,在调用之后, game.ship
保持未初始化(或者NULL
,或者在调用之前它的值是什么)。 因此,您也会丢失对新分配的船舶的引用,并泄漏内存。
您需要将指针传递给指针才能更改它:
static void create_ship(struct ship **ship) { *ship = malloc(sizeof(struct ship)); // ...
并在通话中: create_ship(&game.ship);
您也可以选择将新船作为函数返回值传递出去:
static ship *create_ship() { struct ship *ship = malloc(sizeof(struct ship)); // ... return ship; } // ... game.ship = create_ship();