2017-05-06 118 views
1

我一直在学习C语言中的结构,当我尝试执行这段代码时,出现了Segmentation错误。为什么我在C中遇到分割错误?

struct hero { 
    char *name; 
    struct hero_properties *prop; 
}; 

struct hero_properties { 
    int damage; 
    int health; 
}; 

int main(int argc, char **argv) 
{ 
    struct hero pudje; 

    define_hero_name(&pudje, "pudje"); 
    set_hero_properties(&pudje, 65, 760); 
    get_hero_info(&pudje); 

    return 0; 
} 

void set_hero_properties(struct hero *name, int damage, int health) 
{ 
    name->prop->damage = damage; 
    name->prop->health = health; 
} 

void define_hero_name(struct hero *name, char *d_name) 
{ 
    name->name = d_name; 
} 

void get_hero_info(struct hero *name) 
{ 
    printf("%s characteristics:\n", name->name); 
    printf("damage: %d\n", name->prop->damage); 
    printf("health: %d\n", name->prop->health); 
} 

正如我意识到它在表达的错误,但为什么?

name->prop->damage = damage; 
name->prop->health = health; 
+6

使其指向任何地方和不确定的行为随之而来你永远不指定任何东西'prop'。将编译器的警告和错误转到最大值。也开始使用调试器,它会告诉你发生了什么事情。 –

+0

,但是当我在gdb中调试这个时 print name-> prop-> damage 这不是错误,我看到一个正确的结果 – Devart

+0

你的'define_hero_name'函数也没有做你认为它的工作。它不会复制名称。相反,它只会复制指向该名称的指针。根据您稍后在游戏中的使用情况,读取此名称可能也会导致分段错误。 – FRob

回答

1

的这里的问题是,hero结构只保留一个指向hero_properties结构。它自己的指针不会给你一个实际的内存来写属性。由于英雄与其属性之间存在很强的联系,因此您可能希望hero_properties结构成为hero结构的一部分。然而,这要求hero_properties结构是hero前的定义:

struct hero_properties { 
    int damage; 
    int health; 
}; 

struct hero { 
    char *name; 
    struct hero_properties prop; 
}; 

然后,你必须访问与点符号的元素,而不是箭:

name->prop.damage = damage; 
+0

thx为那个家伙:)。然而,是否有可能将'hero_properties'设置为'hero'之后? – Devart

+0

@Devart不,C不知道'struct hero_properties'是什么,直到你声明它。您将收到一条错误消息,指出'error:field'prop'具有不完整类型。 – anonymoose

0

以供将来参考,以帮助您调试,所以你不必等待SO回复,你应该考虑编译gcc -g -o YourExecutableName NameOfYourFileToCompile.c -Wall,这将在调试模式下编译并显示所有编译器警告,然后你可以运行一个你选择的调试器,它应该显示哪一行导致段错误。

无论如何,萨米在评论中指出,问题是,你永远在hero.prop指针指向hero_properties结构,正因为如此,当您试图访问name->prop->damage,你是铸造和取消引用的内存,你有没有实际分配给任何东西;因此分段错误。为了您的具体问题,你可以这样解决这个问题:

int main(int argc, char **argv) 
{ 
    struct hero pudje; 
    struct hero_properties props; // allocates an instance of hero_properties to the stack 
    pudje.prop = &props; // provides hero.prop with the pointer to that instance of the structure 

    define_hero_name(&pudje, "pudje"); 
    set_hero_properties(&pudje, 65, 760); 
    get_hero_info(&pudje); 

    return 0; 
} 
相关问题