我使用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;
}
答案 0 :(得分:6)
您需要传递共享指针,而不是直接传递给int的引用和指针。
正在发生的事情是共享指针永远不会传递到test_shared_ptr()函数之外的任何地方。当该函数返回时,共享指针被销毁。当它发现其他任何东西都没有引用它的内存时,就会破坏它所指向的内存。
基本上,您使用int &i
和int *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指针并自行删除。