2017-05-06 71 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; 
} 
相關問題