2012-03-08 25 views
1

我有一個包裝類爲int,名爲intWrapper,並且將兩個數相加的函數addN,定義如下:不同的行爲在Visual C++相比MingW平臺

intWrapper* addN(intWrapper *first, intWrapper *second) 
{ 
    intWrapper c; 
    c.setData(first->getData() + second->getData()); 
    return &c; 
} 

然後,在主( )功能我這樣做:

intWrapper first(20), second(40); 
intWrapper* t = addN(&first, &second); 
cout << (*t).getData() << endl; 

在開發 - C++(MINGW32)這個執行如預期,並打印出值60,但在Visual C++我得到的值-858993460
但是,如果我使用new關鍵字在addN函數內創建一個新對象,則它在Visual C++中也會輸出60。我很好奇爲什麼發生這種情況。有什麼想法嗎?
全部代碼是在這裏:

#include <iostream> 
using namespace std; 

template<typename T, T defaultValue> 
class Wrapper 
{ 
     private: T n_; 
     public: 
      Wrapper(T n = defaultValue) : n_(n) {} 
      T getData() 
      { 
        return n_; 
      } 
      void setData(T n) 
      { 
        n_ = n; 
      } 
}; 

typedef Wrapper<int, 47> intWrapper; 

intWrapper* addN(intWrapper *first, intWrapper *second) 
{ 
    intWrapper c; 
    c.setData(first->getData() + second->getData()); 
    return &c; 
} 

int main() 
{ 
    intWrapper p; 
    cout << p.getData() << endl; 
    intWrapper first(20), second(40); 
    intWrapper* t = addN(&first, &second); 
    cout << (*t).getData() << endl; 
    system("PAUSE"); 
    return 1; 
} 
+0

另請注意,VC++喜歡用0xbaadf00d,0xcccccccc,0xffffffff等值填充每一塊可能存在的「不良內存」。在你的情況下,你已經得到值0xFFFFFFFFCCCCCCCC,這看起來像程序吞嚥了一些嘔吐物。 – ActiveTrayPrntrTagDataStrDrvr 2012-03-08 09:59:02

+0

你應該習慣於啓用高警告級別...... – PlasmaHH 2012-03-08 11:08:24

回答

7

這是未定義行爲:你是返回一個指針到一個局部變量函數返回時,這意味着返回值是一個懸擺指針將被破壞。

未定義的行爲意味着任何事情都可能發生:它可能會崩潰,它可能看起來「正常工作」或可能無法正常工作。

當您使用new時,intWrapper實例將超出該函數的範圍,並且不是未定義的行爲,並且可以正常工作(對於VC和MingW32)。不需要時請記住delete返回的intWrapper*

+0

啊,我明白了,這真的很明顯,愚蠢的我。謝謝。 – hero47 2012-03-08 09:58:22

+2

@ hero47如果此答案是針對您的問題的(或最佳)解決方案,那麼[接受](http://meta.stackexchange.com/q/5234/162011)將是正確的答案。 – 2012-03-08 10:21:02

0

在開發 - C++(MINGW32)此執行如預期

按預期它不執行。 該程序使用未定義的行爲。當你這樣做的時候會發生任何事情。

您返回指向局部變量的指針。從函數返回時,局部變量不再存在。這意味着之前由該變量使用的內存可能包含任何東西,或者甚至可能無法再被讀取(即您會遇到段錯誤/訪問衝突)。除非你喜歡玩俄羅斯輪盤賭,並且想要在你的程序中完全不可預知的行爲,否則你不應該那樣做。

按值返回IntWrapper(你需要拷貝構造函數和賦值運算符爲):

intWrapper addN(intWrapper *first, intWrapper *second) 
{ 
    intWrapper c; 
    c.setData(first->getData() + second->getData()); 
    return c; 
} 

,或者用new分配,然後返回結果(和事後忘了刪除)

intWrapper* addN(intWrapper *first, intWrapper *second) 
{ 
    intWrapper *c = new intWrapper; 
    c->setData(first->getData() + second->getData()); 
    return c; 
} 

或者使用智能指針(shared_ptr)自動刪除它。

相關問題