【问题标题】:C++11 storing multiple shared pointers as raw pointersC++11 将多个共享指针存储为原始指针
【发布时间】:2014-06-25 02:28:07
【问题描述】:

我的问题涉及 C++11 中的 shared_ptrmake_shared。我有两个向量,第一个存储智能指针,第二个存储原始指针。第一个向量按我的预期工作,但向量2 只是令人困惑......

代码示例

#include <iostream>
#include <vector>
#include <memory>

int main() {
    std::vector<std::shared_ptr<int>> vector1;
    vector1.push_back(std::make_shared<int>(1));
    vector1.push_back(std::make_shared<int>(2));
    vector1.push_back(std::make_shared<int>(3));

    std::vector<int*> vector2;
    vector2.push_back(std::make_shared<int>(4).get());
    vector2.push_back(std::make_shared<int>(5).get());
    vector2.push_back(std::make_shared<int>(6).get());

    std::cout << "vector1 values:" << std::endl;
    for(auto &value: vector1) { std::cout << *value << std::endl; }

    std::cout << "vector2 values:" << std::endl;
    for(auto &value: vector2) { std::cout << *value << std::endl; }

    return 0;
}


输出

vector1 values:
1
2
3
vector2 values:
6
6
6


问题

我意识到创建原始指针而不是尝试转换智能指针会简单得多,但这让我很想知道为什么会发生这种情况?还有为什么每次推送都会改变vector2中的所有值?


链接

以下是我在 stackoverflow 中发现的一些问题,但他们没有回答我的问题,或者我可能没有理解答案...

【问题讨论】:

  • 第一个问题很好!格式很好。

标签: c++ c++11 shared-ptr make-shared


【解决方案1】:

您将使用shared_ptr 的原因是您希望在指向它的所有实例超出范围时释放它指向的内存。 shared_ptr 在您调用 .get() 后立即被销毁,因此您立即有一个悬空指针。取消引用操作的结果是未定义的,这意味着它可能会或可能不会返回一个有意义的值,或者它甚至可能会做一些完全不相关的事情(比如崩溃)。

这是一项功能。您希望发生这种情况:否则,您将泄漏内存。想象一下这段代码:

vector<int> integers;
integers.push_back(*make_shared<int>(6).get());

如果内存没有被释放,那么之后将没有办法释放它,因为你无法恢复 shared_ptr 的托管指针。

【讨论】:

  • 这现在有点意思了,但是如果std::shared_ptr::get 返回一个全新的指针而不是指向托管对象的指针不是更有意义吗?
  • @Oak,这将强制您与 shared_ptr 一起使用的任何类型都是可复制的,并且由于 C++ 的复制机制,它很可能不适用于多态性。它在大型数据结构上也会非常慢,并且还会给开发人员带来释放指针的负担(这与首先使用shared_ptr 的观点背道而驰)。您也不能将它与数组类型一起使用,因为不可能获得使用new 创建的数组的长度(因此shared_ptr 在返回新指针时不知道要复制多少数据)。跨度>
  • 啊,非常感谢您提供详尽且易于理解的答案:)
  • @Oak 不,因为get() 方法用于从智能指针中提取指针,而不是获取全新的指针。您可能会得到一个“6”作为输出,因为您的三个分配中的每一个都可能获得相同的内存,因此您只能获得最后一个值。但是(如其他地方所述)这是未定义的行为,因为您正在取消引用已被删除的指针。
【解决方案2】:

您正在看到未定义的行为。当你这样做时:

vector2.push_back(std::make_shared<int>(4).get());

您正在创建一个临时的shared_ptr,并将指向其托管对象的指针复制到您的vector 中。这立即变成了一个悬空指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2019-06-30
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 2022-07-10
    相关资源
    最近更新 更多