C++ 如果指针已被删除,指针容器如何拥有指针的所有权?

C++ 如果指针已被删除,指针容器如何拥有指针的所有权?,c++,pointers,c++11,C++,Pointers,C++11,在这段代码中,我试图创建一个模板类p_array,它存储指向对象的指针,如下所示。简单地说,模板类存储指针,如果在使用后没有删除指针,则将其删除。所以我应该做一个NULL检查 尽管这个问题在其他问题中得到了解决。我真的不明白如何检查指针是否为空 在析构函数~p_array()中,检查空指针无效 我尝试了类似的方法,用std::shared_ptr来解释这个想法 p_数组析构函数: ~P_array() { unsigned int i = 0; while(i < tota

在这段代码中,我试图创建一个模板类
p_array
,它存储指向对象的指针,如下所示。简单地说,模板类存储指针,如果在使用后没有删除指针,则将其删除。所以我应该做一个
NULL
检查

尽管这个问题在其他问题中得到了解决。我真的不明白如何检查指针是否为空

在析构函数
~p_array()
中,检查空指针无效

我尝试了类似的方法,用
std::shared_ptr
来解释这个想法

p_数组析构函数:

~P_array() {
    unsigned int i = 0;
    while(i < total)
    {
        if (t_array[i])        //Not effective
        {
            std::cout << "deleting " << t_array[i] << "\n" ;
            delete (t_array[i]); //Ownership of pointer
        }
        i++;
    }
}    
~P_数组(){
无符号整数i=0;
而(i如果容器拥有指针,那么它拥有指针。只是不要在容器外部删除它们。这是容器的工作!任何外部删除都是不正确的。请注意,此代码在语法上是正确的,只是错误:

{
    std::unique_ptr<int> up(new int(42));
    delete up.get();
   // oops, now deleted again
}
如果我删除了一个存储在容器中的指针,该容器删除了析构函数中的指针,那么容器如何知道这些指针是否被准确删除

没有。指针除了指向的对象的地址之外没有其他信息。如果您需要额外的信息来确定该对象是动态分配的,还是已被删除,则需要将其保留在其他位置,如智能指针中

删除指针是否会使其成为空指针

没有

如果容器无法检查删除的指针,那么它如何获得这些指针的所有权,例如在p_数组示例中

使用智能指针,如
std::unique_ptr
std::shared_ptr
,具体取决于它应该具有独占所有权还是共享所有权

如果我删除存储在容器中的指针,该容器将删除 析构函数中的指针,然后容器如何知道 指针是否被准确删除

公认的编程行为是

  • 定义时初始化所有指针
  • 如果要删除指针指向的对象,请将指针设置为NULL
  • 在取消引用之前,始终检查指针是否不为NULL
这种琐碎的编程规则将确保

  • 不会发生双重删除
  • 悬空指针不会导致崩溃
  • 取消引用无效指针不会使程序崩溃

当然,如果您使用智能指针,上述所有问题都可以从本质上得到解决。应该使用的确切智能指针将取决于您的设计。

还有其他建议,建议您使用
std::unique\u ptr
std::shared\u ptr
,您应该调查然后使用,而不要做您似乎想做的事情o

如果您想保留或多或少的代码,那么有一件事您需要了解,那就是您的类
p_数组
应该拥有它包含的指针

为此,析构函数应为:

~P_array() {
    unsigned int i = 0;
    while(i < total)
    {
        std::cout << "deleting " << t_array[i] << "\n" ;
        delete t_array[i];  //Ownership of pointer
        i++;
    }
}
然后,您对控制台的输出将包括:

正在删除0


删除指针不会使其为空。如果需要,必须显式将其设置为空(删除后)。如果有完整的(更小、更简单的)指针,这会更容易。@Cornstalks感谢提供信息,但删除“垃圾数据”后的指针值应该是多少或者其他。是否可以检查删除的指针请参阅。指针值不受删除的影响。指针指向的内存无效,但无法保证“无效”的含义:某些系统将使用一些无效值(即或零或类似值)擦除内存区域.某些系统将保持内存不变。它是由实现定义的。
template <typename T>
using P_Array = std::vector<std::unique_ptr<T>>
~P_array() {
    unsigned int i = 0;
    while(i < total)
    {
        std::cout << "deleting " << t_array[i] << "\n" ;
        delete t_array[i];  //Ownership of pointer
        i++;
    }
}
ap.t_array[0] = 0;  // Null the pointer so that ap no longer owns it.
delete op[0];  // Delete pointer from the copy.