与MingW相比,Visual C ++中的行为不同

时间:2012-03-08 09:48:34

标签: c++ visual-c++ mingw32

我有一个名为intWrapper的int的包装类,以及一个添加两个数字的函数addN,定义如下:

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

然后,在 main()函数中,我这样做:

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

在Dev-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;
}

2 个答案:

答案 0 :(得分:7)

这是未定义的行为:您正在返回一个指向局部变量的指针,该函数在函数返回时将被销毁,这意味着返回值是悬空指针。

未定义的行为意味着任何事情都可能发生:它可能会崩溃,它可能看起来“正常”工作或可能无法正常工作。

当您使用new时,intWrapper实例将存在于函数范围之外,并且不是未定义的行为,并且将正常工作(对于VC和MingW32)。当不再需要时,请记得delete返回的intWrapper*

答案 1 :(得分:0)

  

在Dev-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)自动删除它。