为什么我在C中遇到Segmentation故障?

时间:2017-05-06 18:08:28

标签: c gcc

我一直在学习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;

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

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

无论如何,正如Sami在评论中指出的那样,问题在于您从未将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;
}