2015-08-21 47 views
0

現在我已經使用gm:s引擎製作了幾年的遊戲(我向你保證我不是一些使用拖放的新手,因爲這些都是經常出現的情況),我決定開始學習要自己使用C++,你知道擴展我的知識和所有好東西= D爲什麼「a-> content」給我一個地址而不是一個值?

雖然這樣做,我一直在嘗試做一個列表類作爲一個實踐項目,你知道,有一組節點鏈接在一起,然後循環扔這些節點得到一個索引值,那麼這裏是我的代碼,我至少問的代碼有我很難理解

template<class type> 
class ListNode 
{ 
    public: 
     type content; 
     ListNode<type>* next; 
     ListNode<type>* prev; 
     ListNode(type content) : content(content), next(NULL), prev(NULL) {} 
    protected: 
    private: 
}; 
template<class type> 
class List 
{ 
    public: 
     List() : SIZE(0), start(NULL), last(NULL) {} 
     unsigned int Add(type value) 
     { 
      if (this->SIZE == 0) 
      { 
       ListNode<type> a(value); 
       this->start = &a; 
       this->last = &a; 
      } 
      else 
      { 
       ListNode<type> a(value); 
       this->last->next = &a; 
       a.prev = this->last; 
       this->last = &a; 
      } 
      this->SIZE++; 
      return (this->SIZE - 1); 
     } 
     type Find(unsigned int pos) 
     { 
      ListNode<type>* a = this->start; 
      for(unsigned int i = 0; i<this->SIZE; i++) 
      { 
       if (i < pos) 
       { 
        a = a->next; 
        continue; 
       } 
       else 
       { 
        return (*a).content; 
       } 
       continue; 
      } 
     } 
    protected: 
    private: 
     unsigned int SIZE; 
     ListNode<type>* start; 
     ListNode<type>* last; 
}; 

一個主要問題,無論對我,這段代碼看起來很好,它的工作原理是我能夠創建一個沒有崩潰的新列表,並且能夠添加元素到這個列表中,並從列表中返回這些元素的正確索引,但是,除了這個問題出現時正從列表本身一個元素的值,因爲當我跑了下面的測試代碼,它並沒有給我什麼是建給我

List<int> a; 
unsigned int b = a.Add(313); 
unsigned int c = a.Add(433); 
print<unsigned int>(b); 
print<int>(a.Find(b)); 
print<unsigned int>(c); 
print<int>(a.Find(c)); 

現在這個代碼我希望給我

0 
313 
1 
433 

因爲這是什麼被告知要做,但是,它只有一半這樣做,給我

0 
2686684 
1 
2686584 

現在,我在一個迷失的地方,我假設提供的值是某種指針地址,但我根本不明白那些意味着什麼,或者是什麼導致該值成爲那,爲什麼

因此,我問互聯網,跆拳道是導致給予這些值,因爲我在這一點上,如果

我的道歉,這是一個稍微長和漫無邊際感到很困惑,我傾向於寫這樣的東西經常= D

謝謝= D

+0

假設這些是「指針地址」是錯誤的。不要做出假設。 –

+0

另外,它會殺了你使用大寫字母和滿座? –

回答

8

當您存儲指向局部變量的指針並稍後取消引用這些指針時,代碼中有大量undefined behaviors。一旦局部變量聲明的範圍結束,它們就會被銷燬。

實施例:

if (this->SIZE == 0) 
{ 
    ListNode<type> a(value); 
    this->start = &a; 
    this->last = &a; 
} 

一旦結束括號達到if體的範圍結束,並且可變a被破壞。此變量的指針現在是所謂的雜散指針並且以任何方式使用它都會導致未定義的行爲。

的解決方案是使用動態new分配的對象:

auto* a = new ListNode<type>(value); 

或者,如果你沒有一個C++ 11能夠編譯

ListNode<type>* a = new ListNode<type>(value); 
+0

感謝小夥子們,但爲了不鬆動指針上下文,必須做些什麼? – Tirous

0

的第一個建議:使用的valgrind或類似的內存檢查器來執行這個程序。您可能會發現由於解引用堆棧指針超出範圍而導致的內存錯誤很多。

第二個建議:瞭解堆棧上的對象和堆上的對象之間的區別。 (提示:你想在這裏使用堆對象。)

第三個建議:瞭解指針「所有權」的概念。通常你要非常清楚應該使用哪個指針變量來刪除一個對象。最好的方法是使用智能指針std::unique_ptr。例如,你可以決定每個ListNode由其前身擁有:

std::unique_ptr<ListNode<type>> next; 
    ListNode<type>* prev; 

並且列表容器擁有該列表

std::unique_ptr<ListNode<type>> start; 
    ListNode<type>* last; 

這樣的頭節點,編譯器會做很多的你在編譯時爲你工作,而且你不必在運行時非常依賴valgrind。

相關問題