【问题标题】:How to test if a shared pointer has been allocated but not assigned如何测试共享指针是否已分配但未分配
【发布时间】:2021-11-05 21:19:19
【问题描述】:

对于共享指针,如何测试它是否已分配但尚未分配? 例如:

案例 1. 使用 make_shared 创建共享指针

std::shared_ptr<Entity> es = std::make_shared<Entity> ();
std::cout << "es: " << es.get() << std::endl;
if (es) {
    std::cout << "es assigned to something" << std::endl;
} else {
    std::cout << "es not assigned to something" << std::endl;
}
if (es.get() == nullptr) {
    std::cout << "es assigned to nullptr" << std::endl;
} else {
    std::cout << "es not assigned to nullptr" << std::endl;
}

案例 2. 创建指向 nullptr 的原始指针。将 shared_ptr 指向这个原始指针

Entity* raw_entity_ptr2=nullptr;
std::shared_ptr<Entity> es2 = std::shared_ptr<Entity> (raw_entity_ptr2);

std::cout << "es2: " << es2.get() << std::endl;
if (es2) {
    std::cout << "es2 assigned to something" << std::endl;
} else {
    std::cout << "es2 not assigned to something" << std::endl;
}
if (es2.get()==nullptr) {
    std::cout << "es2 assigned to nullptr" << std::endl;
} else {
    std::cout << "es2 not assigned to nullptr" << std::endl;
}

案例 3. 创建指向实例化对象的原始指针。将 shared_ptr 指向这个原始指针。

Entity* raw_entity_ptr=new Entity;
std::shared_ptr<Entity> es3 = std::shared_ptr<Entity> (raw_entity_ptr);

std::cout << "es3: " << es3.get() << std::endl;
if (es3) {
    std::cout << "es3 assigned to something" << std::endl;
} else {
    std::cout << "es3 not assigned to something" << std::endl;
}
if (es3.get()==nullptr) {
    std::cout << "es3 assigned to nullptr" << std::endl;
} else {
    std::cout << "es3 not assigned to nullptr" << std::endl;
}

产生以下输出:

es: 0xa44de0
es assigned to something
es not assigned to nullptr

es2: 0
es2 not assigned to something
es2 assigned to nullptr

es3: 0xa44e20
es3 assigned to something
es3 not assigned to nullptr

如何进行区分案例 1 和案例 3 的测试?

【问题讨论】:

  • 你说的“内存空白”是什么意思?
  • 就是你在做什么,如果(es):en.cppreference.com/w/cpp/memory/shared_ptr/operator_bool,请注意,如果引用计数达到 0,则将 nullptr 分配给 shared_ptr 将释放其关联的内存(en.cppreference.com/w/cpp/memory/shared_ptr/operator%3D)然后删除内存
  • 在你的第一行之后,es 指向一个动态分配的、值构造的Entity(就像Entity{})。一切都已正确初始化,没有明显的任务要做,所以你能澄清你的问题吗?
  • 这与std::shared_ptr无关,您必须从您的对象中处理它。例如,您可以保留 bool 来描述您的对象是否具有指定值。
  • 您无法区分案例1和案例3,因为它们之间没有区别。在这两种情况下,您都有一个shared_ptr,它拥有一个默认构造的Entity

标签: c++ shared-ptr


【解决方案1】:

如何测试是否已分配但尚未分配?

C++ 中没有这样做的机制。

你真的不需要。一般来说,std::shared_ptr&lt;Entity&gt; 要么指向完全构造的 Entity 对象,要么不指向任何地方。

如果默认构造的Entity 处于特殊的“空”状态,则由Entity 的定义来提供测试方法。

例如(使用std::vector&lt;int&gt; 而不是Entity

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

int main() {
    auto es = std::make_shared<std::vector<int>> ();
    std::cout << "es: " << es.get() << std::endl;
    if (es) {
        std::cout << "es assigned to something" << std::endl;
    } else {
        std::cout << "es not assigned to something" << std::endl;
    }
    if (es->empty()) {
        std::cout << "es is empty" << std::endl;
    } else {
        std::cout << "es not empty" << std::endl;
    }
}

我需要什么样的测试来检查“es”既不指向 nullptr 也不指向实例化的实体对象?

没有这样的测试。在正常使用中,这种状态是不可能的。如果您尝试创建一个既不为空也不指向EntityEntity* 类型的指针值,然后使用该指针值,则行为未定义。

您可以将适当对齐和大小的char[] 重新解释为Entity*,将其与合适的删除器一起传递给std::shared_ptr&lt;Entity&gt; 的构造函数,然后在placement-newEntity 那里,但在同时你不能使用共享指针的指针

【讨论】:

    【解决方案2】:

    我需要什么样的测试来检查“es”既不指向 nullptr 也不指向实例化的实体对象?

    没有这样的测试,因为这不是指针的有效状态 - 不适用于 shared_ptr,不适用于 unique_ptr,不适用于 any 指针。一个指针只有两种有效状态——指向有效内存,或者nullptr。其他任何内容都是无效的,并且此类指针的大多数用途都是未定义的行为。

    【讨论】:

    • 不只是取消引用。如果您 == 指向另一个指针的无效值指针,该指针也是未指定的行为
    • shared_ptr sp = make_shared() 执行时,sp​​ 是否指向有效内存?
    • @didjek 是的。它指向一个默认构造的Entitymake_shared 的(在这种情况下为零)参数被转发给构造函数
    猜你喜欢
    • 2021-11-07
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2015-07-14
    相关资源
    最近更新 更多