C++ 删除指向指针的指针

C++ deleting a pointer to a pointer

提问人:Jason Baker 提问时间:9/7/2008 更新时间:12/16/2015 访问量:32527

问:

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

delete [] PointerToPointers;

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

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

C++ 指针

评论


答:

1赞 Matt Sheppard 9/7/2008 #1

恐怕你得绕圈子了。

3赞 Jeffrey 9/7/2008 #2

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

30赞 Jason Cohen 9/7/2008 #3

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

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

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

20赞 Ray 9/8/2008 #4

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

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

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

  delete pI;
  delete [] pArr;

这些 DELETE 语句清除了 “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;

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

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

  ppArr = new int *[3];

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

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

  delete [] ppArr;

  return 0;

}

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

4赞 Greg Rogers 9/13/2008 #5

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

评论

0赞 Frank 9/29/2010
很好,我不知道那些!
0赞 AndreasT 4/16/2009 #6

我不知道为什么这个问题的回答这么令人困惑。

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

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

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

它不在乎它只是删除了一堆地址 对象,它只看到整数。

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

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

编辑: 杰森的回答没有错,只是没有击中要害。也不 编译器和 C(++) 中的其他任何东西都不关心你删除其他地方的东西 指向。你可以这样做。尝试使用已删除对象的其他程序部件 会对你造成故障。但没有人会阻碍你。 当对象时,销毁指向对象的指针数组也不是问题 在别处有参考。

评论

0赞 Ben Voigt 2/15/2010
“尝试使用已删除对象的其他程序部分将对您产生段错误”......段错误可能是最好的结果,它捕获了问题所在的地方。但是还有很多其他的可能性,这些可能性直到以后才会被注意到,甚至可能导致在程序退出后持续损坏(例如,如果在现在的可用内存中分配了文件写入缓冲区)。
3赞 RikSaunderson 9/29/2010 #7

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

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

typedef *Street StreetSign;

如果您有一个路牌数组,并且您删除了路牌数组,这并不意味着您会自动删除这些路牌。他们仍然在那里,砖块和砂浆,他们只是不再有那些指向他们的标志。你已经摆脱了那些指向街道的指针的特定实例。

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

如果你删除指针数组,你所做的只是删除一个整数数组。