【问题标题】:Double free error with a destructor of a Linked List-like class类链表类的析构函数的双重释放错误
【发布时间】:2021-11-30 10:31:10
【问题描述】:

对于学校的一个项目,为了学习 c++,我必须在不同的课程上工作。 其中之一是 Number 类,它是将数字表示为链表:

class Number {
public:
    Number( unsigned long l ) {
        first_ = new Digit{ static_cast< DigitType >( l % number_base ), nullptr };
        if ( l >= number_base ) {
            first_->next_ = (Number( l / number_base )).first_;
        }
    }
    ~Number() {        
        [...]
    }

private:
    using DigitType = unsigned int;
    static const DigitType number_base{ 10u };
    struct Digit {
        DigitType digit_;
        Digit * next_;
    };
    Digit * first_;
};

Number n{ 123 }; 因此将是 n -> 3 -> 2 -> 1 -> nullptr

我必须编写析构函数,所以我采用了类似于单链表的方法:

~Number() {        
        Digit * current_address = first_;
        while (current_address != nullptr) {
            Digit * next_address = current_address->next_;
            delete current_address;
            current_address = next_address;
        }
    }

然后我运行这个简单的 sn-p 看看它是否有效:

//Another file
#include <exception>
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>

#include "Number.hpp"

void print_number() {
    Number n{ 10 };
    std::cout << n << std::endl;
}

int main(int argc, char const *argv[])
{
    std::cout << "Starting..." << std::endl;
    print_number();
    std::cout << "Finished !" << std::endl;
    return 0;
}



./a.out
Starting...
free(): double free detected in tcache 2
Aborted (core dumped)

我想我可能对动态分配有一些误解,因为我觉得我的析构函数不会尝试释放两次相同的地址......知道发生了什么吗?

提前致谢!

【问题讨论】:

  • first_-&gt;next_ = (Number( l / number_base )).first_; 非常有问题,您正在从临时对象分配一个指针(执行此行后将立即调用其析构函数)

标签: c++ class destructor dynamic-memory-allocation


【解决方案1】:

问题出在这里:

first_->next_ = (Number( l / number_base )).first_;

这会创建一个临时编号,在创建后将调用其析构函数,释放内存。

一个更好的方法是简单地使用循环而不是递归。

但是,如果您坚持使用递归,那么不要递归调用构造函数,而是调用具有完全相同逻辑的辅助函数。

我会让你来实现这些想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2012-07-04
    • 2011-05-19
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多