c++ 如何解决我的内存泄漏?

标签 c++ memory copy-constructor

考虑以下整数的二进制类表示形式的实现:

class Binary {
private:
    int *digits;
    int first1;
public:
    Binary() {
        digits = new int[128];
        digits[0]=0;
        first1=0;
    }
    ~Binary() {
        cout<<"deleting"<<endl;
        delete [] digits;
    }
    Binary(const Binary& b){
        digits = new int[128];
        memcpy(digits,b.digits,128*sizeof(int));
        first1=b.first1;
    }
    explicit Binary(double x){
        int n=(int)x,i;
        digits = new int[128];
        for (i=0; n ; i++,n>>=1) digits[i]=(n & 1)? 1:0;
        first1=i-1;
    }
    Binary& operator =(const Binary& b){
        if (this==&b) return *this;
        memcpy(digits,b.digits,128*sizeof(int));
        first1=b.first1;
        return *this;
    }
    Binary(int n) {
        int i;
        digits = new int[128];
        for (i=0; n ; i++,n>>=1) digits[i]=(n & 1)? 1:0;
        first1=i-1;
    }
    void print() {
        for (int i=first1; i>=0 ; i--) cout<<digits[i];
        cout<<endl;
    }
    operator int() {
        int x = 1,sum=0;
        for (int i=0; i<=first1 ; i++,x<<=1) sum+=digits[i]*x;
        return sum;
    }
    Binary& operator +(Binary& a) {
        int overflow = 0;
        Binary* b1=new Binary();
        int max = a.first1>this->first1? a.first1 : this->first1,bit;
        for (int i=0; i<=max ; i++) {
            bit=a.digits[i]+this->digits[i]+overflow;
            overflow=0;
            if (bit>1) overflow=1;
            b1->digits[i]=bit%2;
        }
        return *b1;
    }

};

及其主要用途:

int main() {
    Binary b(91);
    int x=9;
    Binary *b2=new Binary();
    *b2=b+x;
    x=*b2;
    b2->print();
    cout<<" = "<<x;
    cin>>x;
}

让我们谈谈这条线:

*b2=b+x;

首先编译器为int x隐式分配一个新的二进制实例,然后将其作为加法的参数,然后为加法结果创建一个新的二进制实例并将其一点一点地复制到*b2。

问题是,如果您运行此代码,它只会打印 deleting ONCE,而为执行该命令创建了 2 个对象。显然有一个泄漏来自添加代码,我在其中明确创建了一个新对象来返回结果。

Q1:我说的对吗?

Q2:我该怎么做才能克服这个问题?

编辑: 可以找到有关运算符重载主题的答案和更多信息 here

最佳答案

总结:用new分配的对象必须用delete删除。使用 new[] 分配的对象必须使用 delete[] 删除。全局变量和局部变量在其作用域/TU 执行结束时自动删除。在 Binary& operator +(Binary& a) 中,您创建了一个泄漏的 Binary,在 main 中,您创建了另一个 Binary 那是泄露了。

如果这样写 operator+ 就可以避免这些问题:

Binary operator +(Binary& a) const{ //return by value
    Binary b1(*this); //hold it on the stack
    //math here
    return b1; //return by value
}

如果在 main 中你也避免了分配:

Binary b2 = b+x;
x = b2;
b2.print();

这将比您的原始代码更快,更易于阅读和理解,并且不会泄漏。

[其他说明]

为内部数据使用 std::vector 而不是管理您自己的动态数组。 vector 更容易,而且不太可能出错。

通常最好尽可能明确地进行转换(如 int -> Binary)。它增加了打字,但省去了麻烦。这也适用于您的 int 转换运算符。

让你的 const 函数成为 const。现在,如果您得到一个const Binary,您几乎无法用它做任何事情。你不能打印它,你不能向它添加任何东西......

您似乎为每个 int 存储一位,这意味着您使用的空间比所需空间多 97%(浪费了 99.99999995% 的值),这很愚蠢。大多数新手从每个 char 开始 0-9,这只会浪费 50% 的空间。 (虽然这仍然是 96% 的值),但确实很容易理解。

正常的加法是这样的:

Binary& operator+=(const Binary& rhs) { 
    int max = a.first1>this->first1? a.first1 : this->first1,bit;
    for (int i=0; i<=max ; i++) {
        bit=a.digits[i]+this->digits[i]+overflow;
        overflow=0;
        if (bit>1) overflow=1;
        b1->digits[i]=bit%2;
    }
}  
Binary friend operator+(Binary lhs, const Binary& rhs) {  
{return lhs+=rhs;}

关于c++ 如何解决我的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11352774/

相关文章:

c++ - 带有浮点/ double 值的 std::numeric_limits<T>::min() 问题

c++ - 如果不在结构中初始化 vector ,它会自动为空还是会具有随机内存位置的值?

c++ - 为什么调用复制构造函数而不是 move 构造函数?

c++ - 类的成员复制

c++ - 带引用计数的复制构造函数

java - C++ 注入(inject) Java 应用程序

c++ - 将 rgb 深度图像转换为 oni 文件

c++ - 结构内的类

C# 试图解密文件以仅处理内存

c - 我最喜欢的段错误!!为什么?