将内存分配给空类会导致内存泄漏吗?

Does allocating memory to an empty class casues memory leak?

本文关键字:内存 泄漏 分配      更新时间:2023-10-16

以下函数出现在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;
}
}

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

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

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 ;
}

你必须始终将newdelete匹配,将new[]delete[]匹配,而不是将它们混合。

为了完整性(我猜上下文(,因为函数的名称是allocChildren我认为他们的意图是new[]数组而不是清理内存。希望以后能有一个匹配的deallocChildrendelete[]这段记忆。

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

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获取成员函数中分配数组的地址。

因此,其他一些代码负责释放分配的内存。

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

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>的析构函数中(。

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