簡體   English   中英

釋放內存

[英]Deallocating memory

對於一個項目,我必須實現一個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。 這修復了assign方法中的核心轉儲,但是我在解構函數中仍然遇到錯誤。

我認為您應該在第二個構造函數中將bitset初始化為NULL

為什么?

因為指針變量不一定要初始化為NULL 因此,當您使用第二個構造函數時,您可能試圖delete[]一些隨機內存地址。

因此,您應該具有:

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

您很可能是在某個地方復制Bitset 您尚未定義副本構造函數,而不是副本分配運算符。 復制的結果是,您有兩個實例,他們兩個都認為他們應該在完成時取消分配動態分配的數組。

這被稱為三規則 :如果您定義析構函數,復制構造函數或復制賦值運算符中的任何一個,則很有可能需要定義所有三個

現在,關於您的代碼:

#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。 您可能要在此處使用<limits.h> CHAR_BIT 或僅使用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();
}

干杯,……

確保分配大小不為零,我懷疑這是這里發生的事情,並且您只是在寫入未分配的垃圾內存。 在valgrind下運行也會捕捉到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM