C++ 11将多个共享指针存储为原始指针

Oak*_*Oak 16 c++ shared-ptr make-shared c++11

我的问题shared_ptrmake_sharedC++ 11有关.我有两个向量,第一个存储智能指针,第二个存储原始指针.第一个向量就像我已经过了一样,但是vector2只是令人困惑......

代码示例

#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;
}
Run Code Online (Sandbox Code Playgroud)


产量

vector1 values:
1
2
3
vector2 values:
6
6
6
Run Code Online (Sandbox Code Playgroud)


我意识到创建原始指针并且不尝试转换智能指针会更简单但是让我很好奇知道为什么会发生这种情况?另外为什么每次推送都会改变vector2中的所有值?


链接

以下是我在stackoverflow中发现的一些问题,但他们没有回答我的问题,或者我不明白答案......

zne*_*eak 11

您将使用a的原因shared_ptr是,当指向它的所有实例超出范围时,您希望释放它指向的内存.在shared_ptr你打电话后立即被破坏.get()它,让你马上有一个悬摆指针.取消引用操作的结果是未定义的,这意味着它可能会或可能不会返回有意义的值,或者它甚至可以执行完全不相关的操作(如崩溃).

这是一个功能.你希望这种情况发生:否则,你会泄漏记忆.想象一下这段代码:

vector<int> integers;
integers.push_back(*make_shared<int>(6).get());
Run Code Online (Sandbox Code Playgroud)

如果内存是没有释放,就没有办法在事后释放它,因为没有办法可以恢复的shared_ptr的托管指针.

  • @Oak,这会强制你使用`shared_ptr`的任何类型都是可复制的,并且由于C++的复制机制,它很可能不适用于多态.在大型数据结构上它也会非常慢,并且它还会给开发人员带来释放指针的负担(这与首先使用`shared_ptr`的观点相反).您也无法将它与数组类型一起使用,因为无法获得使用`new`创建的数组的长度(因此`shared_ptr`在返回新指针时不知道要复制多少数据). (2认同)

jua*_*nza 10

您看到未定义的行为.当你这样做:

vector2.push_back(std::make_shared<int>(4).get());
Run Code Online (Sandbox Code Playgroud)

您正在创建一个临时的shared_ptr,并将指向其托管对象的指针复制到您的vector.这立即成为一个悬垂的指针.