具有指针和Node嵌套类的Tree结构中的内存泄漏

我需要执行此任务,其中必须定义一个具有嵌套的私有Node类的Tree类。
问题是我既不能使用smart pointers也不能使用std::vector,也不能使用复制运算符和复制分配。我只允许使用原始指针。
因此,我编写了该类,并使用 valgrind 进行了测试,以检查是否存在内存泄漏,并且确实如此。我知道内存泄漏可能是由于Node类引起的,因为我不是free _children,但是当我这样做时,会遇到分段错误。
我真的不知道该如何解决这个问题。

非常感谢您。

mingkaifeng22 回答:具有指针和Node嵌套类的Tree结构中的内存泄漏

T** getChildren() { return &this->children; }

返回children成员的地址。稍后,您可以通过以下操作通过数组索引取消引用来使用该地址:

_info->getChildren()[index] = childTree;

这正在调用未定义的行为。要解决这个问题:

将您的会员身份更改为:

Tree** _children;

将您的ctor更改为:

Node(T data) 
    : _data( std::move(data) ),_children(new Tree<T,N>*[N]()),_isWord(false)
{
}

并注意指针语法数组以及元素的值初始化,这将使该数组零填充。

最后,将getChildren()成员更改为:

Tree** getChildren() { return this->_children; }

那应该可以减轻您的UB,并减轻您的过失。不会为此涂糖衣。在这种情况下,手动内存管理容易出错且存在问题。如果没有保证的话,至少使用智能指针会更好。但这就是它。

替代

完全丢失动态children分配。它的大小已经由N的编译时规范确定。所以用那个。

成员变得简单:

Tree* _children[N];

ctor仍然可以通过以下方式进行值初始化:

Node(T data) 
    : _data( std::move(data) ),_children(),_isWord(false)
{
}

并从析构函数中完全删除delete [] children;

,

好吧,这不是带有大量内存泄漏方法的清理代码。 我认为这是您遇到的一个问题:

Tree() : _info(nullptr) {} 
...
~Tree() {
    delete _info;
  }

但是,当然,还有更多地方可能出问题:

Tree& operator= (Tree&& t) // check _info not null before calling delete _info

用语言来说-您的class Tree有两个构造函数。接受类型为TTree(T data)的值的值。该构造函数确实创建了一个new节点。这是用于在Tree函数中创建main()的构造函数。

您有另一个构造函数:默认构造函数。这是从class Node_children = new Tree<T,N>[N];

创建子节点时调用的构造函数。

此默认构造器Tree() : _info(nullptr)不会创建新的_info节点。

程序结束并且调用了析构函数后-试图删除nullptr

简单的解决方法是更改​​Tree析构函数:

~Tree() {
    if (_info) delete _info;
  }

Node::_children是一个Trees数组,当您调用getChildren时,您将返回一个指针数组。因此,调用ins可能会破坏内存。否则可能会偶然起作用。

最好将getChildren更改为将引用返回给elemet,方法是: Tree& getChildren(int index) { return _children[index]; }

或将_children的def更改为Tree** _children; 初始化为_children = new Tree<T,N>*[N];

本文链接:https://www.f2er.com/3129742.html

大家都在问