1

我有一个 int 的包装类,命名为intWrapper,以及一个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) 中,它按预期执行,并将打印 value 60,但在 Visual C++ 中我得到 value -858993460
但是,如果我使用 new 关键字在 addN 函数中创建一个新对象,它60也会在 Visual C++ 中输出。我很好奇为什么会发生这种情况。有什么想法吗?
完整代码在这里:

#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;
}
4

2 回答 2

7

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

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

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

于 2012-03-08T09:51:40.640 回答
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)自动删除。

于 2012-03-08T12:22:46.027 回答