C++ 为什么我需要手动删除向量中的指针?
为什么我需要手动删除vector中动态创建的项?为什么它们不会被删除,或者在向量被删除时调用它的析构函数 通常是这样的,但为什么需要呢C++ 为什么我需要手动删除向量中的指针?,c++,memory-management,destructor,C++,Memory Management,Destructor,为什么我需要手动删除vector中动态创建的项?为什么它们不会被删除,或者在向量被删除时调用它的析构函数 通常是这样的,但为什么需要呢 vector<int*> v; for (vector<int*>::iterator it = v.begin(); it != v.end(); ++it) { delete *it; } 向量v; for(vector::iterator it=v.begin();it!=v.end();++it) { 删除*它;
vector<int*> v;
for (vector<int*>::iterator it = v.begin(); it != v.end(); ++it)
{
delete *it;
}
向量v;
for(vector::iterator it=v.begin();it!=v.end();++it)
{
删除*它;
}
向量的实现只是为了删除它的内存。指针没有解构器。而在C++中,没有垃圾收集或逻辑来查看它是指针和递归删除它。
如果您想参加下一次ISO会议并提议,请成为我的嘉宾,但对我来说,我只是将其放入内联
函数中:
template<class T>
public static inline void deleteVectorPointer(std::vector<T*> v)
{
for (vector<T*>::iterator i = v.begin(); i != v.end(); i++)
{
delete *i;
}
}
模板
公共静态内联void deleteVectorPointer(std::vector v)
{
对于(向量::迭代器i=v.begin();i!=v.end();i++)
{
删除*i;
}
}
不会调用析构函数,因为指针不拥有它所指向的对象
在C++11中,std::unique_ptr
确实拥有它所指向的对象。在本例中,释放指针时调用析构函数,这可能是您想要的行为。(如果您没有C++11编译器,但有一个相当新的前C++11编译器,unique_ptr
仍然作为TR1的一部分提供。)因为语言无法知道您是否需要它们在完成后保持活动状态。如果您插入一些指向堆栈对象或类似对象的指针,会怎么样?轰
但是,这可以通过使用智能指针来解决,智能指针将实现自动销毁的适当策略unique_ptr
和shared_ptr
是最常见和最有用的。首先,在向量中存储原始指针。这些指针只是指针。他们可以指向任何地方。它们可以指向本地对象,delete
无法删除这些对象。即使它们指向动态创建的对象,也不一定意味着用户希望它们与向量一起消亡。向量怎么会知道这些
这是一个对象所有权的问题。任何拥有该对象的人都有责任正确、及时地删除该对象。普通原始指针不表示所有权。这就是为什么vector不能对是否需要删除对象做出任何假设。如果要告诉向量它拥有其动态对象,请使用相应的智能指针
其次,请注意,在一般情况下,您的删除技术不一定是安全的。一些标准容器假定存储在其中的数据始终有效。当您在每个向量元素上执行delete
操作时,向量中的数据将变为“无效”(指针变得不确定)。这是一个向量。但在“更智能”的容器中执行类似操作,例如std::map
或std::unordered_set
,可能并将导致问题。即使随后立即销毁容器本身,容器的销毁算法也完全可能需要分析(比较、散列等)单个元素的值。你用你的自行车把他们都杀了
聪明的指针自然会解决这个问题。但是,如果必须对存储在标准容器中的原始指针使用手动delete
,则更好的步骤顺序是
在i
处检索元素的值,并将其存储在指针p
从容器中删除i
处的元素
是否删除p
最后,您将得到一个空容器和
delete
d数据。同样,您的方法将适用于简单序列,如std::vector
或std::list
,但不要对有序或散列序列执行此操作。如果您有指针向量,它将获得指针的RID。不会调用析构函数,因为指针本身没有析构函数。@Ynau他在问为什么必须删除指针上的数据。vector怎么知道您的项是“动态创建的”?在向量中存储指针。指针可以指向任何地方。它们可以指向动态对象。它们可以指向静态对象。它们都可以指向同一个局部对象。你认为向量应该如何识别和处理所有这些情况呢?std::vector
可以做到,不需要任何清理功能。C++11并不认为这很糟糕:而且在11之前就有很多实现可以接受>
。只有在C++11中才是标准的。回答很好,关于过早删除std::map
等中的元素的危险性,我不理解在std::map
中删除元素的问题。删除指针不会改变它的值,对吗?@rafak:当你有一个存储指针的std::map
时,大多数时候你会使用一个比较函数来比较指针对象,而不是指针本身。但你已经摧毁了那些尖锐的物体。因此,如果在那一刻之后,地图出于某种原因决定进行比较,它将失败。这实际上取决于实施情况<代码>标准::映射我看到的实现不会这样做。但是GCC实现中的hash_-map
:如果预先删除这样的指向对象,它将在析构函数中崩溃。@AndreyT:好的,谢谢你的精确性。我以为你指的是比较指向不在同一数组中的对象的指针的不特定性。