2014-03-29 60 views
0

我真的很難確定爲什麼這個程序是segfaulting。我在對象Park中使用包含對象指針的std :: list。一切似乎工作正常,但是當我使用列表的迭代器,並嘗試調用一些對象的方法,它segfaults。爲什麼這個C++程序段錯誤?

我發現如果我將std:list<Felid*>的類型修改爲std:list<Felid*>*,就沒有更多的segfault。我想明白爲什麼這是行得通的?

我編譯此相剋++:g++ -g -Wall -std=c++11 main.cpp

main.cpp

#include <iostream> 
#include <list> 

class Felid { 
    public: 
     void do_meow() { 
      this->meow(); // <-- Segfault occurs, why ? 
     } 
    protected: 
     virtual void meow() = 0; 
}; 

class Park { 
    public: 
     std::list<Felid*> getFelids() { 
      return this->felids; 
     } 

     void add_felid(Felid* f) { 
      this->getFelids().push_back(f); 
     } 

     void listen_to_felids() { 
      for (std::list<Felid*>::iterator it = this->getFelids().begin(); it != this->getFelids().end(); it++) 
      { 
       (*it)->do_meow(); // <-- will Segfault 
      } 
     } 
    protected: 
     std::list<Felid*> felids; 
}; 



class Cat : public Felid { 
    protected: 
     void meow() { std::cout << "Meowing like a regular cat! meow!\n"; } 
}; 

class Tiger : public Felid { 
    protected: 
     void meow() { std::cout << "Meowing like a tiger! MREOWWW!\n"; } 
}; 



int main() { 
    Park* p = new Park(); 

    Cat* cat = new Cat(); 
    Tiger* tiger = new Tiger(); 

    p->add_felid(cat); 
    p->add_felid(tiger); 

    p->listen_to_felids(); // <-- will Segfault 
} 

回答

1

的問題是與std::list<Felid*> getFelids()方法返回。它按值返回列表,所以每次調用它時都會得到一份新列表。您應該返回與std::list<Felid*>&

該段錯誤一提的是,因爲你的迭代器的begin()end()來自不同列表(因爲你正在做的每個副本的時候),所以迭代器永遠不會到達第一個列表的end()和不斷去通過隨機記憶。

此外,您正在迭代的列表僅僅是一個臨時的列表,所以當您嘗試使用迭代器時就消失了。

+0

當我將getFelids的返回類型更改爲'std :: list &getFelids()'時,它仍然不起作用T_T,但我現在明白了更多。 – Nico

+0

如果你這樣做會失敗嗎?它適用於我(不是那必然意味着很多) – Khoth

+0

我仍然因爲某些原因得到了段錯誤=/ – Nico

1

std::list<Felid*> getFelids()

這將返回列表的副本。對其進行的任何更改都不會影響班級中的felids。更改返回類型std::list<Felid*>&

1

的關鍵問題是,你是按值引用返回比下面列表

std::list<Felid*> getFelids() { 
     return this->felids; 
    } 

這裏getFelids不返回將貓科動物中的std ::名單的副本,並於不會添加到原始類成員中。當你通過指針返回時,你正在修改原來的類成員。

右方式將是通過指針(標準::列表<> *)或​​參照(標準::列表<> &)

相關問題