如何保留局部变量的值并在C ++中重新访问外部

时间:2010-06-29 14:31:40

标签: c++ shared-ptr

我使用boost shared_ptr来包装指针。但是我只能在test_shared_ptr()中获取正确的值,而在main()中,我得到了错误的值。

  
    

预期产量:
    100
     100

         

实际输出:
    100个
    -572662307

  

在这种情况下,指针似乎变得无效。有没有正确的方法来完成这项工作?提前谢谢。

以下是源代码。

#include <memory>
#include <iostream>


class TestClass
{
public:
    TestClass(int &i);
    void print_i();
private:
    int *_i;
};

TestClass::TestClass(int &i) : _i(&i)
{

}

void TestClass::print_i()
{
    std::cout << *_i << std::endl;
}


void print_i(int &i)
{
    std::cout << i << std::endl;
}

TestClass *test_shared_ptr()
{
    std::tr1::shared_ptr<int> i(new int());

    *i = 100;

    print_i(*i); 

    return new TestClass(*i);
}


int main(int argc, char** argv)
{
    TestClass *p = test_shared_ptr();
    p->print_i();
    return 0;
}

4 个答案:

答案 0 :(得分:6)

您需要传递共享指针,而不是直接传递给int的引用和指针。

正在发生的事情是共享指针永远不会传递到test_shared_ptr()函数之外的任何地方。当该函数返回时,共享指针被销毁。当它发现其他任何东西都没有引用它的内存时,就会破坏它所指向的内存。

基本上,您使用int &iint *i的位置都会更改为使用std::tr1::shared_ptr<int> i

您可能需要更多地阅读共享指针。基本上,它们为它们指向的指针保留引用计数。当它们被复制时,它们会引用引用计数,当它们被销毁时,它会减少它。当引用计数达到0(没有别的东西引用它所指向的内存时)它会释放该内存。因此,即使在您的情况下某些东西使用了该指针,因为它没有使用共享指针,因此共享指针无法知道内存仍在使用,因此它可以释放它。

答案 1 :(得分:2)

  

在这种情况下,指针似乎变得无效

当然它变得无效。当你离开test_shared_ptr时,shared_ptr会被删除,之后我就不存在了。

  

任何正确的方法来完成这项工作?

1)简单地复制i的值。 (在TestClass中使用int i而不是int * i)。 int很小,你不会丢失任何东西。

2)使用std :: tr1 :: shared_ptr&lt; int&gt;而不是在TestClass中的int *。

答案 2 :(得分:1)

您遇到的问题是您的API合同。

  

我不想使用共享指针在TestClass的构造函数中传递变量值,因为我不想强制api用户使用智能指针

您的TestClass合约目前看起来像是希望调用者维护int项,以使其有效期超过TestClass

但是,您的测试用例不遵循此合同规则。

  

实际上我想在我的应用程序中通过引用而不是泛型类型传递对象。

通过引用或指针传递与'generic'类型无关。

以下是对您的API进行代码测试的可能修复方法,int的范围会更长,然后足够长(直到应用程序的结尾)才能处理TestClass

中的所有用法
TestClass *test_shared_ptr(int &i)
{
    i = 100;

    print_i(i); 

    return new TestClass(i);
}


int main(int argc, char** argv)
{
    std::tr1::shared_ptr<int> i(new int());

    TestClass *p = test_shared_ptr(*i);
    p->print_i();
    return 0;
}

答案 3 :(得分:0)

你在做什么真的打破了shared_ptr的重点。基本上当你把它传递出那个函数时,它是否神奇地应该打破,因此,不会释放指向太多的记忆?

没有。它解放了它。您是否期望shared_ptr仍然存在于函数之外,以便当“p”超出范围时它会设法调用teh shared_ptr析构函数?这不可能发生。 p是指针而不是shared_ptr类。

返回shared_ptr或返回new'd指针并自行删除。