C++ 删除包含重复项的指针的动态数组

C++ 删除包含重复项的指针的动态数组,c++,arrays,duplicates,delete-operator,C++,Arrays,Duplicates,Delete Operator,在这里释放内存的正确方法是什么? 指针数组包含重复项 class HashTable { Bucket<E>** index = new Bucket<E>*[indexSize]; ... } ~ExtHash( ) { for (size_t i = 0; i < indexSize; ++i) delete index[i]; delete[] index; } 类哈希表 { 桶**索引=新桶*[indexSize]

在这里释放内存的正确方法是什么? 指针数组包含重复项

class HashTable
{
   Bucket<E>** index = new Bucket<E>*[indexSize];
   ...
}

~ExtHash( ) 
{
  for (size_t i = 0; i < indexSize; ++i) 
     delete index[i];

   delete[] index;
 }
类哈希表
{
桶**索引=新桶*[indexSize];
...
}
~ExtHash()
{
对于(大小i=0;i
在您的情况下,以这种方式存储原始指针是危险的。最好使用std::shared_ptr,只需重置共享指针。重置所有指针后,它们将被安全释放。

在您的情况下,以这种方式存储原始指针是危险的。最好使用std::shared_ptr,只需重置共享指针。重置所有指针后,它们将被安全释放。

可能是这样的:

~ExtHash( ) 
{
  std::sort(index, index + indexSize);
  size_t new_end = std::unique(index, index + indexSize) - index;

  for (size_t i = 0; i < new_end; ++i) 
     delete index[i];

   delete[] index;
 }
~ExtHash()
{
标准::排序(索引,索引+索引大小);
size\u t new\u end=std::unique(索引,索引+索引大小)-索引;
对于(大小i=0;i
可能是这样的:

~ExtHash( ) 
{
  std::sort(index, index + indexSize);
  size_t new_end = std::unique(index, index + indexSize) - index;

  for (size_t i = 0; i < new_end; ++i) 
     delete index[i];

   delete[] index;
 }
~ExtHash()
{
标准::排序(索引,索引+索引大小);
size\u t new\u end=std::unique(索引,索引+索引大小)-索引;
对于(大小i=0;i
排序
索引
,使用
std::unique
删除相邻的重复项。O(N log N),这是最好的了。

排序
索引
,用
std::unique
删除相邻的重复项。O(N logn),这是最好的了。

我会仔细考虑是否希望这个容器负责删除对象;将它们存储在其他地方会更简单,只使用此容器引用它们,而不是管理它们的生命周期

或者,您可以使用
std::shared_ptr
来管理对象;然后,当您放弃所有这些内容时,它们将被自动删除

如果你真的想这样做,你需要删除每一个副本后删除它们;差不多

for (size_t i = 0; i < indexSize; ++i) {
    Bucket<E> * victim = index[i];
    indexSize = std::remove(index+i+1, index+indexSize, victim) - index;
    delete victim;
}
(大小i=0;i{ 桶*受害者=索引[i]; indexSize=std::remove(index+i+1,index+indexSize,牺牲品)-索引; 删除受害者; }
[注意:这段代码可能是错误的;我在编写它时确实犯了几个错误。如果您真的想以艰难的方式管理动态对象,那么您需要对其进行彻底的测试]

我会仔细考虑您是否希望此容器负责删除对象;将它们存储在其他地方会更简单,只使用此容器引用它们,而不是管理它们的生命周期

或者,您可以使用
std::shared_ptr
来管理对象;然后,当您放弃所有这些内容时,它们将被自动删除

如果你真的想这样做,你需要删除每一个副本后删除它们;差不多

for (size_t i = 0; i < indexSize; ++i) {
    Bucket<E> * victim = index[i];
    indexSize = std::remove(index+i+1, index+indexSize, victim) - index;
    delete victim;
}
(大小i=0;i{ 桶*受害者=索引[i]; indexSize=std::remove(index+i+1,index+indexSize,牺牲品)-索引; 删除受害者; }
[注意:这段代码可能是错误的;我在编写它时确实犯了几个错误。如果你真的想以艰难的方式管理动态对象,那么你需要对它进行彻底的测试]

每次创建指针时,
将它推回向量。该向量将保存您创建的所有指针,并且每个指针只保存一次

稍后,迭代该向量并删除指针。
这就像编写自己的简单垃圾收集器。

每次创建指针时,
将其推回到向量中。该向量将保存您创建的所有指针,并且每个指针只保存一次

稍后,迭代该向量并删除指针。
这就像编写自己的简单垃圾收集器。

使用一个集合来删除重复项:

std::set<Bucket*> uniqueBuckets(index, index + indexSize);

for(Bucket* bucket: uniqueBuckets)
    delete bucket;
std::设置唯一存储桶(索引,索引+索引大小);
用于(桶*桶:唯一桶)
删除bucket;

使用集合删除重复项:

std::set<Bucket*> uniqueBuckets(index, index + indexSize);

for(Bucket* bucket: uniqueBuckets)
    delete bucket;
std::设置唯一存储桶(索引,索引+索引大小);
用于(桶*桶:唯一桶)
删除bucket;

“重复”是指,对相同的元素的指针?是的,像这个索引[0 ] -> 0x123,索引[1 ] -> 0x45 6,索引[2 ] -0x123不是C++对这个自动的鲁棒性吗?@如果你摧毁了一个对象,那么任何指向该对象的指针或引用都会变成一个活手榴弹。删除一个对象两次(就像这段代码一样)会产生未定义的行为。谢谢@Mike。嗯,它不可能100%健壮,但只要存储一些不太可能发生的字节序列。。。我认为C++可以是99.99%个健壮的:-)你是指指向相同元素的指针吗?是的,像这个索引[0 ] -> 0x123,索引[1 ] -> 0x45 6,索引[2 ] -0x123不是C++对这个自动的鲁棒性吗?@如果你摧毁了一个对象,那么任何指向该对象的指针或引用都会变成一个活手榴弹。删除一个对象两次(就像这段代码一样)会产生未定义的行为。谢谢@Mike。嗯,它不可能100%健壮,但只要存储一些不太可能发生的字节序列。。。我认为C++可以是99.99%健壮的:-是的,这比我的答案中的多义代码更有效,而且更少出错。是的,这比我的答案中的多义代码更有效,更容易出错。或者,将对象本身保存在一个列表中(不是向量,因为你希望指针在更多的时候被添加到它们中,以保持有效)。这样您就根本不需要
new
delete
;列表将自动为您销毁它们。或者,将对象本身保留在列表中(而不是向量,因为您希望指向它们的指针在添加更多对象时保持有效)。这样您就根本不需要
new
delete
;该列表将自动为您销毁它们。