VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 734|回复: 2

[已解决]析构函数和空间释放

[复制链接]
67_avatar_middle
最佳答案
0 
donate_vip 发表于 2021-6-24 15:38:12 | 显示全部楼层 |阅读模式
本帖最后由 虚怀若谷smile 于 2021-6-25 08:42 编辑

我最近在看基础课程的视频学习,学到类的析构函数和运算符重载,看到syc老师写的相关例子,想动手试试。但是发现新建的两个对象stud_1和stud_2,在test()函数运行完成时空间释放需调用析构函数释放new出来的字符数组,发现两次进入析构函数释放的都是stu2的字符数组,所以第二次就崩溃了,这是为什么?哪里出了问题呢?程序如下
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class CStudent
{
public:
        char* pname;
        char sex;
        int num;
        int age;

public:
        CStudent(char* t_pname, char t_sex, int t_num, int t_age) :sex(t_sex), num(t_num), age(t_age)  //构造函数1
        {
                int len = strlen(t_pname) + 1;
                pname = new char[len];
                memset(pname, 0, len);
                strcpy_s(pname, len, t_pname);
        };
        CStudent() {};//构造函数2

        ~CStudent()//析构函数
        {
                if (pname)
                {
                        delete[]pname;
                }
        }
        CStudent operator=(CStudent& stu)//等号运算符重载
        {
                this->age = stu.age;
                this->sex = stu.sex;
                this->num = stu.num;
                int len = strlen(stu.pname) + 1;
                this->pname = new char[len];
                memset(this->pname, 0, len);
                strcpy_s(pname, len, stu.pname);
                return *this;
        }
};

void test()
{
        CStudent stud_1("zhangsan", 'f', 1001, 20);
        CStudent stud_2;
        stud_2 = stud_1;
}
int _tmain(int argc, _TCHAR* argv[])
{
        test();
        return 0;
}
最佳答案
51_avatar_small
2021-6-25 21:47:40
因为执行这条语句的时候会产生一个临时的对象,这个临时的对象跟 stud_2 内部的pname所指向的地址是一样的,所以释放两次就会报错!

一种解决办法是添加个拷贝构造函数:
  1.         CStudent(CStudent& stu)
  2.         {
  3.                 this->age = stu.age;
  4.                 this->sex = stu.sex;
  5.                 this->num = stu.num;
  6.                 int len = strlen(stu.pname) + 1;
  7.                 this->pname = new char[len];
  8.                 memset(this->pname, 0, len);
  9.                 strcpy_s(pname, len, stu.pname);
  10.         };//拷贝构造函数
复制代码




上一篇:vs2013 如何导出和导入所有断点?
下一篇:CListCtrl::GetColumnOrderArray
51_avatar_middle
最佳答案
90 
online_admins 发表于 2021-6-25 21:47:40 | 显示全部楼层    本楼为最佳答案   
bestAnswer
因为执行这条语句的时候会产生一个临时的对象,这个临时的对象跟 stud_2 内部的pname所指向的地址是一样的,所以释放两次就会报错!

一种解决办法是添加个拷贝构造函数:
  1.         CStudent(CStudent& stu)
  2.         {
  3.                 this->age = stu.age;
  4.                 this->sex = stu.sex;
  5.                 this->num = stu.num;
  6.                 int len = strlen(stu.pname) + 1;
  7.                 this->pname = new char[len];
  8.                 memset(this->pname, 0, len);
  9.                 strcpy_s(pname, len, stu.pname);
  10.         };//拷贝构造函数
复制代码
67_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-6-25 22:56:55 | 显示全部楼层
Syc 发表于 2021-6-25 21:47
因为执行这条语句的时候会产生一个临时的对象,这个临时的对象跟 stud_2 内部的pname所指向的地址是一样的 ...

按您说的,也就是通过拷贝构造函数来实现由stud_1向stud_2赋值,或者说叫复制吧。您说的产生临时对象,是不是在等号运算符重载时new出的那个临时对象,那个对象在运算符重载结束时,返回*this时又复制了一个对象给stud_2, 所以产生了双份?如果运算符重载的返回类型是 CStudent&类型呢,我又重新看了一遍您的视频讲解,发现返回的是CStudent类对象的引用,按照您之前说的,运算符重载中生成的对象就跟stud_2是同一个对象了,这样应该也行吧。
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2023-12-3 19:15

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表