21

所以我有一个指向指针数组的指针。如果我像这样删除它:

delete [] PointerToPointers;

这也会删除所有指向的指针吗?如果没有,我是否必须遍历所有指针并删除它们,或者有更简单的方法吗?我的 google-fu 似乎没有给我这个问题的任何好的答案。

(是的,我知道我需要使用向量。这是学校里那些“赶上 C++”类型的作业之一。)

4

7 回答 7

30

是的,您必须遍历指针,单独删除。

原因:如果其他代码有指向数组中对象的指针怎么办?C++ 编译器不知道这是否正确,所以你必须明确。

对于“更简单的方法”,有两个建议: (1) 为此目的制作一个子例程,这样至少您不必多次编写代码。(2) 使用“智能指针”设计范例,您可以在其中保存一个带有引用计数器的对象数组,然后当任何代码不再引用这些对象时删除这些对象。

于 2008-09-07T03:24:13.833 回答
20

我同意 Jason Cohen 的观点,尽管我们可以更清楚地说明需要使用循环删除指针的原因。对于每个“新”或动态内存分配,都需要“删除”一个内存解除分配。有时可以隐藏“删除”,就像智能​​指针一样,但它仍然存在。

int main()
{
  int *pI = new int;
  int *pArr = new int[10];

到目前为止,在代码中我们已经分配了两块动态内存。第一个只是一个通用的 int,第二个是一个 int 数组。

  delete pI;
  delete [] pArr;

这些删除语句清除“new”分配的内存

  int ppArr = new int *[10];

  for( int indx = 0; indx < 10; ++indx )
  {
    ppArr[indx] = new int;
  }

这段代码正在执行前面的两个分配。首先,我们在动态数组中为我们的 int 创建空间。然后我们需要循环并为数组中的每个点分配一个 int。

  for( int indx = 0; indx < 10; ++indx )
  {
    delete ppArr[indx];
  }
  delete [] ppArr;

请注意我分配此内存的顺序,然后我以相反的顺序取消分配它。这是因为如果我们要执行 delete [] ppArr; 首先,我们会丢失告诉我们其他指针是什么的数组。该块或内存将返回给系统,因此无法再可靠地读取。

  int a=0;
  int b=1;
  int c=2;

  ppArr = new int *[3];

  ppArr[0] = &a;
  ppArr[1] = &b;
  ppArr[2] = &c;

这个我觉得也应该提一下。仅仅因为您正在使用指针并不意味着这些指针指向的内存是动态分配的。也就是说,仅仅因为你有一个指针并不意味着它一定需要被删除。我在这里创建的数组是动态分配的,但是指针指向 int 的本地实例当我们删除它时,我们只需要删除数组。

  delete [] ppArr;

  return 0;

}

最后,动态分配的内存可能会很棘手,无论如何你可以像在智能指针中一样安全地包装它,或者使用 stl 容器而不是你自己的容器可以让你的生活更加愉快。

于 2008-09-07T18:36:41.957 回答
4

请参阅boost pointer container以了解为您自动删除包含的指针的容器,同时保持非常接近普通 STL 容器的语法。

于 2008-09-12T16:44:53.383 回答
3

指针几乎只是内存引用,而不是漂亮的小自清洁 .net 对象。为每个类创建适当的析构函数将使删除比整个代码中的大量循环更干净。

于 2008-09-07T03:22:22.810 回答
3

让我们举一个(伪编码)现实世界的例子。想象一下你有一个这样的类:

class Street
{
    public:
        Street();
        ~Street();
    private:
        int HouseNumbers_[];
}

typedef *Street StreetSign;

如果您有一组街道标志,并且您删除了一系列街道标志,这并不意味着您会自动删除这些街道。他们还在那里,砖头和灰浆,只是不再有那些迹象指向他们。你已经摆脱了那些指向街道的特定实例。

指针数组(在概念上)有点像整数数组,它是一个数字数组,表示各种对象的内存位置。不是对象本身。

如果你 delete[] 指针数组,你所做的就是删除一个整数数组。

于 2010-09-29T13:43:45.453 回答
1

我想你将不得不循环,我害怕。

于 2008-09-07T03:20:25.670 回答
0

我不知道为什么回答得这么长。

如果删除指针数组,您将释放用于通常为整数数组的内存。
指向对象的指针是包含地址的整数。

您删除了一堆地址,但没有对象。

delete 不关心内存空间的内容,它调用析构函数并将内存标记为空闲。

它不关心它只是删除了一堆对象的地址,它只看到整数。

这就是为什么你必须先循环遍历数组!并在每个元素上调用 delete,然后您可以删除数组本身的存储。

好吧,现在我的回答有点长…………奇怪……;)

编辑:杰森的回答没有错,只是没能做到。编译器和 c(++) 中的任何其他内容都不关心您删除其他地方指向的内容。你可以做到。尝试使用已删除对象的其他程序部分将对您产生段错误。但是没有人会阻碍你。当对象在别处被引用时,销毁指向对象的指针数组也不是问题。

于 2009-04-15T16:25:39.860 回答