如果指针已经被删除,指针容器怎么能拥有指针的所有权
How can pointers container can have the ownership of pointers if pointers are already deleted?
在这段代码中,我试图创建一个模板类P_array
,它存储指向对象的指针,如下所示。简单地说,模板类存储指针,如果使用后没有删除,则将其删除。所以我应该做一个NULL
检查。
尽管这个问题在其他问题中得到了解决。我真的不知道如何检查指针是否为NULL。
在析构函数~P_array()
中,检查NULL指针是无效的。
我使用std::shared_ptr
尝试了类似的方法来解释这个想法。
p_array析构函数:
~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++;
}
}
main.cpp:
#include <iostream>
#include <memory>
#include "p_array.h"
class Obj {
public: ~Obj () { std::cout << "Deleting Obj...n" ;}
};
int main() {
P_array<Obj> ap;
Obj * op[10];
for (int i = 0; i < 10 ; i++)
{
op[i] = new (Obj);
ap.add(op[i]);
}
std::shared_ptr <Obj> sp = std::make_shared<Obj>();
//if (sp.get()) delete sp.get() ; // invalid pointer error
sp.reset();
//delete op[0] ;// gives double free error
}
所以我的问题很简单:
如果我删除了存储在容器中的指针,该容器会删除析构函数中的指针。那么容器如何知道这些指针是否真的被删除了?
删除指针会使其成为
NULL
指针吗?如果容器不能检查已删除的指针,那么它如何获得这些指针的所有权,例如在
P_array
示例中?
如果我删除了存储在容器中的指针,该容器会删除析构函数中的指针。那么容器如何知道这些指针是否被实际删除?
没有。指针除了所指向对象的地址之外没有其他信息。如果你需要额外的信息来确定该对象是否是动态分配的,或者它是否已被删除,你需要将其保存在其他地方,比如智能指针中。
删除指针会使其成为NULL指针吗?
否。
如果容器不能检查已删除的指针,那么它如何获得这些指针的所有权,例如在p_array示例的情况下
使用像std::unique_ptr
或std::shared_ptr
这样的智能指针,具体取决于它应该具有独占所有权还是共享所有权。
如果我删除了存储在容器中的指针析构函数中的指针,然后容器如何知道这些指针被删除了?
是公认的编程行为
- 定义时初始化所有指针
- 如果要删除指针所指向的对象,请将指针设置为NULL
- 在取消引用之前,始终检查指针是否不为NULL
这种琐碎的编程规则将确保
- 不会发生双重删除
- 悬挂指针不会导致崩溃
- 取消引用无效指针不会使程序崩溃
当然,如果使用智能指针,上述所有问题都可以固有地处理。应该使用的确切智能指针将取决于您的设计。
-
如果容器拥有指针,那么它就拥有
{ std::unique_ptr<int> up(new int(42)); delete up.get(); // oops, now deleted again }
程序员应该知道不要那样做。
-
没有。它只需要释放内存供以后使用,不必触摸指针或将其指向的内存清零或诸如此类的事情。
-
这是班级合同的一部分。它只是拥有指针。时期析构函数应该无条件地删除其指针,除非您向
release()
(借用unique_ptr
的方法)公开它们的方法。
注意,在C++11中,您可以简单地将其实现为:
template <typename T>
using P_Array = std::vector<std::unique_ptr<T>>
还有其他使用std::unique_ptr
或std::shared_ptr
的建议,您应该调查并使用这些建议,而不是做您想要做的事情。
如果你想或多或少地保留你所拥有的代码,那么有一件事你需要理解,那就是你的类P_array
应该拥有它所包含的指针。
为此,你的析构函数应该是:
~P_array() {
unsigned int i = 0;
while(i < total)
{
std::cout << "deleting " << t_array[i] << "n" ;
delete t_array[i]; //Ownership of pointer
i++;
}
}
注意,这里不必测试null
指针,因为delete 0;
是nop
。
我注意到在main.cpp
中,您将指针存储在两个不同的容器中,但当您调用ap.add(op[i]);
时,您必须考虑ap
现在拥有该指针。
稍后,您会收到一个注释掉的delete op[0];
,它给了您两次删除。你应该做的是这样的事情:
ap.t_array[0] = 0; // Null the pointer so that ap no longer owns it.
delete op[0]; // Delete pointer from the copy.
您向控制台的输出将包括:
删除0
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- 为什么"具有常量成员的结构"类型的指针不能指向"具有非常量成员的结构"?
- 我们怎么能 me 字符数组只接受 C++ 中的字母
- 为什么智能指针不能用通常的指针方式声明
- 你怎么能emplace_back错误的类型?
- 除了调用全局删除运算符之外,删除一个void指针还能做什么呢
- 我怎么能有一个以2D数组为参数的函数,而数组有一个我想更改的参数/维度
- 我怎么能把它转换成c++呢
- 我有一个调用ID3D11DeviceContext::CopySubresourceRegion的循环.我怎么能强制等待
- 类定义怎么能不占用内存?
- 怎么能用memcpy复制工会简单的成员?
- 智能指针不能自动用作原始指针
- 指针怎么能有一个字符串作为它的值
- 这两个指针怎么能有相同的值
- 如果指针已经被删除,指针容器怎么能拥有指针的所有权
- 我怎么能用这个OpenMP关键部分来避免这个原始指针呢
- 在C++中,如果没有dynamic_cast,我怎么能将一个子类实例从一个基类指针转换到另一个基类
- 我怎么能理解,如果一个指针被删除在c++
- 我怎么能写一个函数的定义在模板类中声明返回指针结构对象