释放内存

时间:2010-11-16 02:45:41

标签: c++ memory delete-operator

对于一个项目,我必须实现一个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();
}

我的问题是我在解构器和assign方法核心转储中的删除语句。是否没有必要释放这段记忆?从我到目前为止所读到的,每当你调用new时总是需要使用delete命令。

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

3 个答案:

答案 0 :(得分:4)

我认为您应该在第二个构造函数中初始化bitsetNULL

为什么呢?

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

所以你应该:

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

答案 1 :(得分:1)

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

这被称为三个规则:如果您定义任何析构函数,复制构造函数或复制赋值运算符,那么您可能需要定义所有三个 EM>

现在,关于你的代码:

#include "bitset.h"

行。

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

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

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

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

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

(4)一般来说,在分配方面表达建筑并不是一个好主意。相反,在建设方面表达意见。

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

(5)检查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();
}

干杯&amp;第h。,

答案 2 :(得分:0)

确保分配大小不为零,我怀疑这是在发生什么,而你只是写入未分配的垃圾内存。在valgrind下运行也会抓住这个。