2016-09-11 26 views
-2

我有幾個類來處理在遊戲中設置玩家選擇的區域。通過指針獲取公共類成員時出現分段錯誤

Region類:

class Region 
{ 
public: 
    string name; 

    Region(string n) : name(n) {} 
} 

玩家控制器類:

class PlayerController 
{ 
public 
    Region* playerRegion 
} 

的RegionHandler類:

class RegionHandler 
{ 
public: 

    enum RegionCode { EU, RU, SEA, AM, CH, AF}; 

    PlayerController playerController; 

    vector<Region> regions; 

    RegionHandler() { 
     static const char *names[] = { "russia", "sea", "america", "china", "africa"}; 
     for (auto n : names) 
      regions.emplace_back(n); 
    } 


    void chooseRegion() { 

     int playerRegionIndex; 

     cout << "Regions:\n" 
      << "0. Europe\n" 
      << "1. Russia\n" 
      << "2. SEA\n" 
      << "3. America\n" 
      << "4. China\n" 
      << "5. Africa\n"; 

     do { 
      cout << "Select a region\n> "; 
      cin >> playerRegionIndex; // Get user to input a region int 
     } 

     while(playerRegionIndex < 0 || playerRegionIndex > 5); 

     playerController.playerRegion = &regions[playerRegionIndex]; 
    } 
} 

主營:

int main() 
{ 
    RegionHandler regionHandler; 
    PlayerController playerController; 

    regionHandler.chooseRegion(); 

    string mystr = playerController.playerRegion->name; 

} 

但是,當我嘗試獲取玩家已選擇的字符串或cout區域的名稱時,我應該可以做到,但即使名稱是應該在RegionHandler中設置的公共字符串,也會出現分段錯誤。我沒有得到其他錯誤,否則程序正常工作。之後我進入一個號碼playerRegionIndex,由string mystr = playerController.playerRegion->name;

我從來沒有遇到過的分段錯誤造成的,我真的不明白了GDB的輸出,這就是爲什麼我問發生

段故障這個。在GitHub

編上新的Ubuntu猛砸爲Windows使用g++ main.cpp -std=c++1y -o main -g

GDB輸出

完整的源:

Program received signal SIGSEGV, Segmentation fault. 
0x00007f6f237ab45b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
+1

解決此類問題的正確工具是您的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –

+6

'regionHandler.chooseRegion()'設置'regionHandler.playerController'。 'main'中的局部變量'playerController'不受影響,它的'playerRegion'成員保持未初始化,包含垃圾。還要注意,你有6個'RegionCode's,但'regions'中只有5個元素。 –

+0

@πάνταῥεῖ我不確定你看過我的問題。我提供了可編譯程序的完整源代碼以及所有可以合併到main.cpp中的相關代碼行,並編譯成可以正常工作。我已經給出了gdb輸出並解釋說我不太瞭解它。在我的代碼中,我儘可能簡潔,並且我不只是傾倒它,要求人們爲我調試它。我不明白是什麼導致了這個問題,這就是我問這個問題的原因。 – exitcode

回答

1

像伊戈爾說,在主playerController局部變量沒有被影響局部變量regionHandler。我仍然在學習OOP,所以如果我錯了,請糾正我,但playerController的區域由regionHandler.chooseRegion()方法設置。這是兩個類之間的依賴關係。

class PlayerController 
{ 

private: 

public 
    Region* playerRegion; 
    PlayerController() 
    {... 
     RegionHandler handle; 
     string region = handle.getRegion(); //using RegionHandler class's method 
     playerRegion = new Region(region); 
     ... 
    } 

} 

class RegionHandler 
{ 
public: 

    enum RegionCode { EU, RU, SEA, AM, CH, AF}; 

    PlayerController playerController; 

    vector<Region> regions; 

    RegionHandler() { 
     static const char *names[] = { "russia", "sea", "america", "china", "africa"}; 
     for (auto n : names) 
      regions.emplace_back(n); 
    } 


    string chooseRegion() { //change the return type to string 

     int playerRegionIndex; 

     cout << "Regions:\n" 
      << "0. Europe\n" 
      << "1. Russia\n" 
      << "2. SEA\n" 
      << "3. America\n" 
      << "4. China\n" 
      << "5. Africa\n"; 

     do { 
      cout << "Select a region\n> "; 
      cin >> playerRegionIndex; // Get user to input a region int 
     } 

     while(playerRegionIndex < 0 || playerRegionIndex > 5); 

     return &regions[playerRegionIndex]; 
    } 
} 
相關問題