gpt4 book ai didi

c++ - 一个简单的 std::shared_ptr 构造案例的段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:13 25 4
gpt4 key购买 nike

来自 cppreference我了解到 std::shared_ptr 有一个构造函数:

template< class Y > explicit shared_ptr( Y* ptr );

然后我试了一段代码如下:

#include <string>
#include <memory>
#include <iostream>

int main(void) {
/// block 1
{
std::shared_ptr<std::string> s1(new std::string("good"));
std::shared_ptr<std::string> s2(s1.get()); /// s2
std::cerr << s2.use_count() << std::endl;
}
/// block 2
{
std::shared_ptr<int> i1(new int(1));
std::shared_ptr<int> i2(i1.get()); /// i2
std::cerr << i2.use_count() << std::endl;
}
return 0;
}

它会导致 block 1 的段错误,但不会导致 block 2,但是 use_count 都是 1。我能想到的区别是int 是原始类型,而 std::string 由分配器管理。

我阅读了gcc-4.9bits/shared_ptr.h,发现这个构造函数有一个后置条件:

use_count() == 1 && get() == __p

问题一:

std::shared_ptr 不应该用一个被另一个智能指针引用的原始指针构造吗?从这个意义上说,使用此构造函数的首选方式是否如下?

std::shared_ptr<T>(new T(...));

问题2:

标准是否对这个构造函数有明确的要求,或者这个后置条件仅适用于libstdc++

最佳答案

这两种情况都是 std::shared_ptr 的无效使用。

您不能将相同的原始指针传递给两个 std::shared_ptr 构造函数并期望得到明确定义的结果。 两者 std::shared_ptr 将相信他们拥有该指针,并在超出范围时尝试将其删除。

这是双重免费,无效。

如果你想有两个 std::shared_ptr 来管理同一个对象,你可以用原始指针构造其中一个(或者,更好的是,使用 std::make_shared ),并且然后从第一个复制构造/分配第二个。这样,只有当那些 std::shared_ptrlast 超出范围时,内存才会被释放(并触发对象的析构函数)。

在第一种情况而不是第二种情况下出现段错误的原因可能是因为 int 是一种普通类型,因此您没有查看释放的指针运行 int 的析构函数,因为它没有析构函数。

关于c++ - 一个简单的 std::shared_ptr 构造案例的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25255389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com