0

对于一个项目,我必须实现一个 bitset 类。到目前为止,我的代码是:

头文件

#ifndef BITSET_H_
#define BITSET_H_
#include <string>
#include <cmath>

using namespace std;

// Container class to hold and manipulate bitsets
class Bitset {
public:
    Bitset();
    Bitset(const string);
    ~Bitset();

    // Returns the size of the bitset
    int size();

    // Sets a bitset equal to the specified value
    void operator= (const string);

    // Accesses a specific bit from the bitset
    bool operator[] (const int) const;

private:
    unsigned char *bitset;
    int set_size;
    // Sets a bitset equal to the specified value
    void assign(const string);
};
#endif /* BITSET_H_ */

源文件

#include "bitset.h"

Bitset::Bitset() {
    bitset = NULL;
}

Bitset::Bitset(const string value) {
    bitset = NULL;
    assign(value);
}

Bitset::~Bitset() {
    if (bitset != NULL) {
        delete[] bitset;
    }
}

int Bitset::size() {
    return set_size;
}

void Bitset::operator= (const string value) {
    assign(value);
}

bool Bitset::operator[] (const int index) const {
    int offset;

    if (index >= set_size) {
        return false;
    }

    offset = (int) index/sizeof(unsigned char);
    return (bitset[offset] >> (index - offset*sizeof(unsigned char))) & 1;
}

void Bitset::assign(const string value) {
    int i, offset;

    if (bitset != NULL) {
        delete[] bitset;
    }

    bitset = new unsigned char[(int) ceil(value.length()/sizeof(unsigned char))];

    for (i = 0; i < value.length(); i++) {
        offset = (int) i/sizeof(unsigned char);
        if (value[i] == '1') {
            bitset[offset] |= (1 << (i - offset*sizeof(unsigned char)));
        } else {
            bitset[offset] &= ~(1 << (i - offset*sizeof(unsigned char)));
        }
    }

    set_size = value.length();
}

我的问题是我在解构器和分配方法核心转储中的删除语句。不需要释放这个内存吗?从我目前所读到的内容来看,每当你调用 new 时,总是需要使用 delete 命令。

编辑:我已经更改了上面的代码以反映其中一个修复程序。我在构造函数中添加了 bitset = NULL。这修复了分配方法中的核心转储,但是我仍然在解构器中遇到错误。

4

3 回答 3

4

bitset我认为你应该NULL在你的第二个构造函数中初始化。

为什么?

因为指针变量不一定会初始化为NULL. delete[]因此,当您使用第二个构造函数时,您可能会尝试一些随机内存地址。

所以你应该有:

Bitset::Bitset(const string value) : bitset(NULL)
{
    assign(value);
}
于 2010-11-16T02:50:39.317 回答
1

很可能您正在复制Bitset某处。您尚未定义复制构造函数,而不是复制赋值运算符。复制的结果是您有两个实例,它们都认为他们应该在完成时释放动态分配的数组。

这就是所谓的三法则:如果您定义了析构函数、复制构造函数或复制赋值运算符中的任何一个,那么您很可能需要定义所有三个

现在,关于您的代码:

#include "bitset.h"

好的。

Bitset::Bitset() {
    bitset = NULL;
}

(1) 您没有包含保证定义的标题NULL

(2) 您没有初始化 member set_size,因此索引运算符中的检查可能/将使用具有未定义行为的不确定值。

(3) 通常更喜欢使用初始化列表而不是赋值(这避免了例如在赋值之后进行默认构造)。

Bitset::Bitset(const string value) {
    bitset = NULL;
    assign(value);
}

(4) 一般来说,用赋值来表达构造并不是一个好主意。相反,在构造方面表达分配。

Bitset::~Bitset() {
    if (bitset != NULL) {
        delete[] bitset;
    }
}

(五)NULL不需要检查的;您可以安全地delete使用空指针。

int Bitset::size() {
    return set_size;
}

(6) 呃,嗯,set_size是那个没有被初始化的成员……另外,这个成员函数应该是const.

void Bitset::operator= (const string value) {
    assign(value);
}

(7) 赋值运算符通常应该返回对被赋值对象的引用。这只是一个约定,但它是您班级的用户所期望的。

(8) 通过值或引用传递参数const。通常,对于内置类型,选择按值,对于其他类型,例如std::string,选择对 的引用const。也就是说,形式论证最好是string const& value

bool Bitset::operator[] (const int index) const {
    int offset;

    if (index >= set_size) {
        return false;
    }

    offset = (int) index/sizeof(unsigned char);
    return (bitset[offset] >> (index - offset*sizeof(unsigned char))) & 1;
}

(9) 首先,再次是未初始化的set_size成员。

(10) 然后,注意sizeof(unsigned char)根据定义它是 1。你可能想CHAR_BIT<limits.h>这里使用。或者只使用 8,除非您计划支持 Unisys 计算机(9 位字节)或德州仪器数字信号处理器(16 位字节)。

void Bitset::assign(const string value) {
    int i, offset;

    if (bitset != NULL) {
        delete[] bitset;
    }

(11)NULL不需要检查。

    bitset = new unsigned char[(int) ceil(value.length()/sizeof(unsigned char))];

(12) 如前所述,sizeof(char)定义为 1。

(13) 除法具有整数参数,因此是整数除法,而不是浮点除法。想必你想要的是诀窍(a+b-1)/b

    for (i = 0; i < value.length(); i++) {

(14) 风格:声明一个变量尽可能接近它的第一次使用。这里的意思是i直接在循环头中声明循环计数器,像这样:for( int i = 0, ....

        offset = (int) i/sizeof(unsigned char);

(14) 同上offset。但是对于这个变量,你不打算改变它的值,所以也要声明它const

        if (value[i] == '1') {
            bitset[offset] |= (1 << (i - offset*sizeof(unsigned char)));
        } else {
            bitset[offset] &= ~(1 << (i - offset*sizeof(unsigned char)));
        }

(15) 更好地重新考虑那些轮班操作!

    }

    set_size = value.length();
}

干杯&hth.,

于 2010-11-16T05:02:25.060 回答
0

确保分配大小不为零,我怀疑这就是这里发生的事情,并且您只是在写入未分配的垃圾内存。在 valgrind 下运行也会发现这一点。

于 2010-11-16T02:48:56.883 回答