删除具有堆成员的对象 [duplicate]

Deleting objects with heap members [duplicate]

提问人:elitk19 提问时间:5/13/2019 更新时间:5/13/2019 访问量:78

问:

我正在研究位集实现。位集使用 数组 来存储位。unsigned long long

class bitset{
    typedef unsigned long long uint64;
    uint64* bits;
    ...
}

由于我需要这个位集来存储大量数据,因此我发现当我使用关键字初始化数组以在堆上构建它时,它的效果最好。uint64new

bitset::bitset(int n_bits){
    if (n_bits % 64 !=0) size (n_bits / 64) + 1;
    else size = n_bits / 64;
    this->data = new uint64[size];
}

执行 do 允许我的程序始终如一地允许我的整个程序访问位数组。 我遇到的一个问题是我的析构函数似乎无法删除数据

bitset::~bitset(){
    delete[] this->data;
}

在没有析构函数的情况下工作,我得到了内存泄漏(正如预期的那样),使用析构函数我得到了一个运行时错误,我尝试在谷歌上搜索它无济于事。我对 c++ 相当陌生,因此对类中的堆栈/堆行为的任何见解将不胜感激。Error in `./a.out': double free or corruption (out):

C++ new-operator 删除运算符 堆栈分配

评论

0赞 PaulMcKenzie 5/13/2019
您的类无法实现用户定义的复制构造函数和赋值运算符。答案 (use ) 给出了修复程序,但如果您真的需要知道如何在不引入向量的情况下修复错误,则 3 规则会解释它。查看链接中的“管理资源”部分。std::vector
0赞 elitk19 5/13/2019
我将对此进行研究,因为这是很好的做法,我将实现复制构造函数,但假设说,如果我只是在位集对象的整个生命周期内通过引用传递该对象,我会避免双重释放吗?根据我的理解,通过引用并不能复制。
0赞 PaulMcKenzie 5/13/2019
您提到的问题在于,复制可能发生在您没有检查或可能忘记的地方。为了缓解这种情况,您应该让编译器告诉您在哪里进行复制,这可以通过制作函数来完成,即 和。但说实话,你应该让你的类可复制。(对我来说)能够放置在使用值语义的容器中更有意义。此外,您应该放入自己的命名空间,因为 C++ 中有一个类deletedbitset(const bitset&) = delete;bitset& operator=(const bitset&) = delete;bitsetbitsetstd::bitset

答:

1赞 eerorika 5/13/2019 #1

您可以使用矢量容器:

class bitset{
    ...
    std::vector<uint64> bits;
    ...

Vector 负责内存分配,这样您就不会遇到多次意外删除内存或意外泄漏内存的问题。


P.S. 不能保证正好是 64 位。它被允许比这更大。如果这对你的程序至关重要,那么你应该改用标准库。这主要只与未来的兼容性有关。unsigned long longstd::uint64_t

评论

0赞 elitk19 5/13/2019
我会试一试。我看到潜在问题的一种方法是,我需要通过套接字发送此位集。我假设所有相同的访问运算符都像数组一样重载?std::vector
0赞 eerorika 5/13/2019
@EliKolb Vector 只是一个包含动态分配数组的容器。成员函数为您提供了一个指向第一个元素的指针,您可以像使用指向数组元素的任何其他指针一样使用该指针(除非您不需要,也不能获得指针的所有权)。data