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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:28:13  来源:igfitidea点击:

C++ deleting a pointer to a pointer

c++pointers

提问by Jason Baker

So I have a pointer to an array of pointers. If I delete it like this:

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

delete [] PointerToPointers;

Will that delete all the pointed to pointers as well? If not, do I have to loop over all of the pointers and delete them as well, or is there an easier way to do it? My google-fu doesn't seem to give me any good answers to this question.

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

(And yeah, I know I need to use a vector. This is one of those "catch up on C++" type assignments in school.)

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

回答by Jason Cohen

Yes you have to loop over the pointers, deleting individually.

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

Reason: What if other code had pointers to the objects in your array? The C++ compiler doesn't know if that's true or not, so you have to be explicit.

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

For an "easier way," two suggestions: (1) Make a subroutine for this purpose so at least you won't have to write the code more than once. (2) Use the "smart pointer" design paradigm where you hold an array of objects with reference-counters, then the objects are deleted when the objects are no longer referenced by any code.

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

回答by Ray

I agree with Jason Cohen though we can be a bit clearer on the reason for needing to delete your pointers with the loop. For every "new" or dynamic memory allocation there needs to be a "delete" a memory de-allocation. Some times the "delete" can be hidden, as with smartpointers but it is still there.

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

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

so far in the code we have allocated two chunks of dynamic memory. The first is just a general int the second is an array of ints.

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

  delete pI;
  delete [] pArr;

these delete statements clear the memory that was allocated by the "new"s

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

  int ppArr = new int *[10];

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

This bit of code is doing both of the previous allocations. First we are creating space for our int in a dynamic array. We then need to loop through and allocate an int for each spot in the array.

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

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

Note the order that I allocated this memory and then that I de-allocated it in the reverse order. This is because if we were to do the delete [] ppArr; first we would lose the array that tells us what our other pointers are. That chunk or memory would be given back to the system and so can no longer be reliably read.

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

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

  ppArr = new int *[3];

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

This I think should be mentioned as well. Just because you are working with pointers does not mean that the memory those pointers point to was dynamically allocated. That is to say just because you have a pointer doesn't mean it necessarily needs to be delete. The array I created here is dynamically allocated but the pointers point to local instances of ints When we delete this we only need to delete the array.

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

  delete [] ppArr;

  return 0;

}

In the end dynamically allocated memory can be tricky and anyway you can wrap it up safely like in a smart pointer or by using stl containers rather then your own can make your life much more pleasant.

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

回答by Greg Rogers

See boost pointer containerfor a container that does the automatic deletion of contained pointers for you, while maintaining a syntax very close to ordinary STL containers.

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

回答by Jeffrey

Pointers are pretty much just memory references and not spiffy little self-cleaning .net objects. Creating proper destructors for each class will make the deletion a little cleaner than massive loops throughout the code.

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

回答by RikSaunderson

Let's take a (pseudocoded) real world example .Imagine that you had a class like this:

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

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

typedef *Street StreetSign;

If you have an array of street signs, and you delete your array of streetsigns, that doesn't mean that you automatically delete the sreets. They re still there, bricks and mortar, they just don't have those signs pointing to them any more. You have got rid of those specificinstances of pointers to the streets.

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

An array of pointers is (conceptually) a bit like an array of integers, it's an array of numbers representing the memory locations of various objects. It isn't the objects themselves.

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

If you delete[] the array of pointers, all you have done is delete an array of integers.

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

回答by Matt Sheppard

I think you're going to have to loop over I'm afraid.

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

回答by AndreasT

I don't know why this was answered so confusingly long.

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

If you delete the array of pointers, you will free the memory used for an array of usually ints.
a pointer to an object is an integer containing the adress.

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

You deleted a bunch of adresses, but no objects.

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

delete does not care about the content of a memory space, it calls a destructor(s) and marks the mem as free.

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

It does not care that it just deleted a bunch of adresses of objects, it merely sees ints.

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

That's why you have to cycle through the array first! and call delete on every element, then you can delete the storage of the array itself.

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

Well, now myanswer got somewhat long... .... strange... ;)

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

Edit: Jason's answer is not wrong, it just fails to hit the spot. Neither the compiler nor anything else in c(++) cares about you deleting stuff that is elsewhere pointed to. You can just do it. Other program parts trying to use the deleted objects will segfault on you. But no one will hinder you. Neither will it be a problem to destroy an array of pointers to objects, when the objects are referenced elsewhere.

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