assertion failure-类中用new创建指针-拷贝构造函数-内存被重复释放

一:拷贝构造函数

1. 浅拷贝:

#include<iostream>
#include<string.h>
using namespace std;
class STRING
{
public:
    //此处补充构造函数
    STRING() {
        str = NULL;
        ct = 0;
    }
    STRING(const char* _str) {
        int i = 0;
        for (; _str[i]; i++);
        ct = i;
        str = new char[i + 1];
        for (int j = 0; j <= i; j++) {
            str[j] = _str[j];
        }
    }
     //此处补充析构函数 
    ~STRING() {

        if (str) delete[]str;
    }
    char* str;//字符指针指向字符串
    int ct;//字符串的长度 
    void show(int t);
};//注意设置show 的参数

void STRING::show(int t = 0) {
    if (t == 0) {
        cout << this->str << endl;
    }
    else {
        for (int i = 0; i < t; i++) {
            cout << this->str[i];
        }
        cout << endl;
    }
}
int main()
{
    STRING str;
    char str_1[] = "hello world";
    STRING str1(str_1); 
    STRING str2 = str1;
    STRING str3("finished");
    str1.show();	//输出 str1 字符串 
    str2.show(3);	//输出 str2 前三个字符 
    str3.show();	//输出 str_3
    return 0;
}

运行结果:

 系统会报错,原因是这个例子调用的是默认的拷贝构造函数,复制构造函数str2是保存在栈中,栈内存在程序结束后自动释放,而堆内存需要显式释放。str2在系统自动调用中使str1的str指针指向了str2的str指针,可以理解为str2在释放时将str1中的指针所指内存释放了,此时str1的str内存已经不存在了,那么delete就释放了一个已经被释放的内存,则会出现错误。解决方法是写复制构造函数的深拷贝。

2. 深拷贝

我们将成员变量换成指针变量,继续实验。

#include<iostream>
#include<string.h>
using namespace std;
class STRING
{
public:
    //此处补充构造函数
    STRING() {
        str = NULL;
        ct = 0;
    }
    STRING(const char* _str) {
        int i = 0;
        for (; _str[i]; i++);
        ct = i;
        str = new char[i + 1];
        for (int j = 0; j <= i; j++) {
            str[j] = _str[j];
        }
    }
    STRING(const STRING& s) {
        str = new char[s.ct + 1];
        for (int j = 0; j <= s.ct; j++) {
            str[j] = s.str[j];
        }
        ct = s.ct;
    }

    //此处补充析构函数 
    ~STRING() {

        if (str) delete[]str;
    }
    char* str;//字符指针指向字符串
    int ct;//字符串的长度 
    void show(int t);
};//注意设置show 的参数

void STRING::show(int t = 0) {
    if (t == 0) {
        cout << this->str << endl;
    }
    else {
        for (int i = 0; i < t; i++) {
            cout << this->str[i];
        }
        cout << endl;
    }
    }
int main()
{
    STRING str;
    char str_1[] = "hello world";
    STRING str1(str_1); 
    STRING str2 = str1;
    STRING str3("finished");
    str1.show();	//输出 str1 字符串 
    str2.show(3);	//输出 str2 前三个字符 
    str3.show();	//输出 str_3
    return 0;
}

可以看到,程序不报错了。

 深拷贝就是给复制构造函数也用new创建内存。

 STRING(const STRING& s) {
        str = new char[s.ct + 1];
        for (int j = 0; j <= s.ct; j++) {
            str[j] = s.str[j];
        }
        ct = s.ct;
    }

总结起来就是先开辟出和源对象一样大的内存区域,然后将需要拷贝的数据复制到目标拷贝对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值