嵌套结构和指针

几乎每次我跳回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();