0

以下函数出现在OctoMap代码中:

class AbstractOcTreeNode {}; -> 他们声明了一个空类

AbstractOcTreeNode** children; -> 这是在OcTreeDataNode类头文件中声明的

template <typename T>
void OcTreeDataNode<T>::allocChildren() {
  children = new AbstractOcTreeNode*[8];
  for (unsigned int i=0; i<8; i++) {
    children[i] = NULL;
  }
}

这不会导致内存泄漏吗?不应该是:

template <typename T>
void OcTreeDataNode<T>::allocChildren() {
  children = new AbstractOcTreeNode*[8];
  for (unsigned int i=0; i<8; i++) {
    delete children[i];
    children[i] = NULL;
  }
}

我错过了什么?谢谢您的帮助!

4

3 回答 3

0

您想删除整个数组,而不是每个单独的数组元素

template <typename T>
void OcTreeDataNode<T>::allocChildren() {
  children = new AbstractOcTreeNode*[8];
  for (unsigned int i=0; i<8; i++) {
    children[i] = NULL;
  }

  // .... later
  delete[] children ;
}

您必须始终将 anew与 a匹配delete,并将 anew[]与 a匹配delete[],而不将它们混合。

为了完整起见(我在上下文中猜测),因为函数的名称是我假设这是他们对数组allocChildren的意图,而不是清理内存。希望以后会有匹配的记忆。new[]deallocChildrendelete[]

于 2019-12-12T16:41:20.830 回答
0
AbstractOcTreeNode** children;

children可以看作是一个指针值数组。

children = new AbstractOcTreeNode*[8];

我们用一个由八个指针值组成的数组来初始化它。

for (unsigned int i=0; i<8; i++) {
    children[i] = NULL;
}

八个children[i]指针值中的每一个最初都是未初始化的AbstractOcTreeNode*。我们将NULL值分配给它们中的每一个。事先调用delete这些未初始化的指针将是未定义的行为。

只有一次内存分配(new[]仅调用一次),其结果保存在children. 只要children最终被清理(使用delete[], 大概在 的析构函数中OcTreeDataNode<T>)就没有泄漏。

您的困惑是具有多个级别的指针的结果,至少其中一些是拥有的。因此,我个人也发现此代码难以阅读。std::vector在现代 C++ 中,您将不会执行手动内存管理,无论是分配指针数组(或者是什么std::array)或分配每个AbstractOcTreeNode-dervied 实例(此处未显示)。您可能会std::vector<std::unique_ptr<AbstractOcTreenode>> children;在现代 C++ 中找到。

于 2019-12-12T16:43:05.053 回答
0

分配内存并立即删除它有什么意义?

template <typename T>
void OcTreeDataNode<T>::allocChildren() {
  children = new AbstractOcTreeNode*[8];
  for (unsigned int i=0; i<8; i++) {
    delete children[i];
    children[i] = NULL;
  }
} 

上面的函数没有意义。

请注意,空类的大小非零。

并且分配了一个指向空类的指针数组。类的对象不在此函数中分配。

在这个函数中

template <typename T>
void OcTreeDataNode<T>::allocChildren() {
  children = new AbstractOcTreeNode*[8];
  for (unsigned int i=0; i<8; i++) {
    children[i] = NULL;
  }
}

命名空间中定义的变量children获取成员函数中分配数组的地址。

所以其他一些代码负责释放分配的内存。

一般来说,类的成员函数使用全局变量是一个坏主意。

于 2019-12-12T16:47:19.093 回答