【问题标题】:Cant delete void pointer from vector in c++无法从 C++ 中的向量中删除 void 指针
【发布时间】:2014-04-24 20:16:42
【问题描述】:

大家好,我试图从向量中删除 void 指针,程序在删除时崩溃。 非常感谢!

template <class T> class tArray_t : public vpArr_t {
  virtual ~tArray_t() {

   for (vector<void*>::iterator it = array.begin() ; it != array.end(); )
   {
          vector<void*>::iterator nextElement = it+1;
          delete *it; // here is the crash
          it = nextElement; 
   }

};

【问题讨论】:

  • 如果它在delete 操作上崩溃,这意味着你在向量中有一个无效的指针;或者至少是一个没有用new分配的指针。
  • C++ 标准第 5.3.5/3 节:[...] an object cannot be deleted using a pointer of type void* because there are no objects of type void.
  • @Nik 因为如果it 等于end(),则无法进入循环体。
  • @Chnossos 如果 it==(lastElement) 然后你执行“it+1”怎么办,你不是在这里越过最后一个元素吗?然后尝试删除不是通过代码分配或可能属于其他代码的位置。
  • @Nik 他实际上是在删除it,而不是nextElement,所以如果它达到了这一点,一切都很好。标准容器确保 end() 始终过去最后一个元素。

标签: c++ pointers vector void


【解决方案1】:

删除void 指针是未定义。你得到的正是你所要求的。

使用vector&lt;T*&gt; 而不是vector&lt;void*&gt;。如果你例如从基类继承 vector&lt;void*&gt;,您必须在删除它之前将指针转换为 T*

delete static_cast<T*>(*it);

您可能还想节省一些工作并使用boost::ptr_vector

【讨论】:

  • 是吗?即使我打电话给operator new(42)?请添加报价。
  • @user3570497:我在您的代码中没有看到任何模板,所以我唯一的建议是按此顺序使用std::unique_ptrboost::variantboost::any
  • @Deduplicator C++ 标准第 5.3.5/3 节:[...] 无法使用 void* 类型的指针删除对象,因为没有 void 类型的对象. 而且如果要删除的对象的动态类型与其静态类型不同,则行为未定义(强调我的)
  • 我认为如果它指向一个带有析构函数的对象,它只是未定义的行为。请参阅 5.3.5.1 的脚注 81 “这意味着无法使用 void* 类型的指针删除对象,因为 void 不是对象类型”。
  • @Jens 它说“这意味着不能使用 void* 类型的指针删除对象”。它没有说“这意味着不能使用 void* 类型的指针删除带有析构函数的对象 ”或类似的东西。阅读所写的内容。
【解决方案2】:

编译器知道使用类型化指针要删除多少字节。这样想,一个 void * 指针没有任何关于它指向的内存的信息,没有人知道如何删除这样的指针。至少,您不知道需要删除什么大小,也不知道要调用哪个析构函数。

Class A;
A * p = new A();
delete p;

执行delete p时,编译器知道需要调用一个destrcutor,需要清理的内存大小为sizeof(A)。一个 void * 指针缺少所有这些信息。

【讨论】:

  • 这不是真的。运行时实现将大小信息保存在该地址的块中。他做不到的真正原因是他使用了错误的delete形式。
猜你喜欢
  • 2013-07-02
  • 2021-06-14
  • 2017-09-10
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
相关资源
最近更新 更多