JayinZig 2025-02-11 21:26 采纳率: 100%
浏览 14
已结题

C++深拷贝及重载赋值运算符出错,找不到问题点

代码如下,写了一个类,然后构造函数用深拷贝的方法,重载赋值运算符,也用的深拷贝的方法。出错了


#ifndef _OPERATOR_H_
#define _OPERATOR_H_

#include <iostream>
using namespace std;

class Opeassignment
{
public:
    int m_age;
    int *m_score;
    Opeassignment();
    Opeassignment(int age, int score);
    Opeassignment(const Opeassignment& p);
    Opeassignment& operator=(const Opeassignment& p);
    ~Opeassignment();
};

void operatormain();
ostream& operator<< (ostream &cout, const Opeassignment &p);


#endif
#include "operator.h"

void operatormain() {
    cout << endl << __FILE__ << ":" << __func__ << " line: " << __LINE__ << endl;
    Opeassignment k1(18,99);
    cout << "k1.m_age :" << k1.m_age << "\tk1.m_score :" << *k1.m_score << endl;
    Opeassignment k2;
    k2.m_age = 20;
    *k2.m_score = 100;
    cout << "k2.m_age :" << k2.m_age << "\tk2.m_score :" << *k2.m_score << endl;
**##error : Segmentation fault (core dumped)!**
    Opeassignment k3(k2);
    cout << "k3.m_age :" << k3.m_age << "\tk3.m_score :" << *k3.m_score << endl;
    Opeassignment k4 = k2;
    cout << "k4.m_age :" << k4.m_age << "\tk4.m_score :" << *k4.m_score << endl;
}

ostream& operator<< (ostream &cout, const Opeassignment &p) {
    cout << __FILE__ << ": " << __func__ << ": " << __LINE__ << endl;
    cout << "Age : " << p.m_age << "\tScore : " << *p.m_score;
    return cout;
}

Opeassignment::Opeassignment() {
    m_score = new int();
}

Opeassignment::Opeassignment(int age, int score) {
    m_age = age;
    m_score = new int(score);
}

Opeassignment::Opeassignment(const Opeassignment& p) {
    m_age = p.m_age;
    if(m_score != NULL) {
        delete m_score;
    m_score = NULL;
    }
    m_score = new int(*p.m_score);
}

Opeassignment& Opeassignment::operator=(const Opeassignment& p){
    m_age = p.m_age;
    if(m_score != NULL) {
        delete m_score;
    m_score = NULL;
    }
    m_score = new int(*p.m_score);
    return *this;
}

Opeassignment::~Opeassignment() {
    if(m_score != NULL) {
        delete m_score;
    m_score = NULL;
    }
}

有大佬能帮忙看看为什么回报错呢,编译环境是G++,linux中编译的,报错内容是:##error : Segmentation fault (core dumped)!
具体是在进行类的拷贝时,以及用等号进行赋值时,会报错感觉是深拷贝有问题,现在正在学习深拷贝的知识,不知道为什么会报错,我用的深拷贝方法,看了好几遍我也没看出问题来。

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-02-11 21:35
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你的代码中存在一些问题,导致在进行深拷贝时出现段错误(Segmentation Fault)。以下是一些可能的问题和解决方案:

    1. 初始化 m_score

    在默认构造函数中,m_score 没有被正确初始化。这会导致未定义行为。

    Opeassignment::Opeassignment() {
        m_score = nullptr; // 初始化为 nullptr
    }
    

    2. 拷贝构造函数中的条件检查

    在拷贝构造函数中,你不应该在复制之前检查 m_score 是否为空。这样会导致不必要的删除操作,并且可能导致未定义行为。

    Opeassignment::Opeassignment(const Opeassignment& p) {
        m_age = p.m_age;
        m_score = new int(*p.m_score); // 直接分配新的内存
    }
    

    3. 赋值运算符中的条件检查

    同样,在赋值运算符中,你不应该在复制之前检查 m_score 是否为空。这样会导致不必要的删除操作,并且可能导致未定义行为。

    Opeassignment& Opeassignment::operator=(const Opeassignment& p){
        if (this != &p) { // 避免自赋值
            m_age = p.m_age;
            delete m_score; // 删除旧的内存
            m_score = new int(*p.m_score); // 分配新的内存
        }
        return *this;
    }
    

    4. 使用智能指针

    为了简化内存管理,可以使用智能指针(如 std::unique_ptrstd::shared_ptr),这样可以避免手动管理内存带来的问题。

    以下是修改后的代码:

    #ifndef _OPERATOR_H_
    #define _OPERATOR_H_
    
    #include <iostream>
    #include <memory> // 包含智能指针头文件
    
    using namespace std;
    
    class Opeassignment
    {
    public:
        int m_age;
        unique_ptr<int> m_score; // 使用智能指针
        Opeassignment();
        Opeassignment(int age, int score);
        Opeassignment(const Opeassignment& p);
        Opeassignment& operator=(const Opeassignment& p);
        ~Opeassignment();
    };
    
    void operatormain();
    ostream& operator<< (ostream &cout, const Opeassignment &p);
    
    #endif
    
    #include "operator.h"
    
    void operatormain() {
        cout << endl << __FILE__ << ":" << __func__ << " line: " << __LINE__ << endl;
        Opeassignment k1(18,99);
        cout << "k1.m_age :" << k1.m_age << "\tk1.m_score :" << *k1.m_score << endl;
        Opeassignment k2;
        k2.m_age = 20;
        *k2.m_score = 100;
        cout << "k2.m_age :" << k2.m_age << "\tk2.m_score :" << *k2.m_score << endl;
        Opeassignment k3(k2);
        cout << "k3.m_age :" << k3.m_age << "\tk3.m_score :" << *k3.m_score << endl;
        Opeassignment k4 = k2;
        cout << "k4.m_age :" << k4.m_age << "\tk4.m_score :" << *k4.m_score << endl;
    }
    
    ostream& operator<< (ostream &cout, const Opeassignment &p) {
        cout << __FILE__ << ": " << __func__ << ": " << __LINE__ << endl;
        cout << "Age : " << p.m_age << "\tScore : " << *p.m_score;
        return cout;
    }
    
    Opeassignment::Opeassignment() : m_score(make_unique<int>()) {}
    
    Opeassignment::Opeassignment(int age, int score) : m_age(age), m_score(make_unique<int>(score)) {}
    
    Opeassignment::Opeassignment(const Opeassignment& p) : m_age(p.m_age), m_score(make_unique<int>(*p.m_score)) {}
    
    Opeassignment& Opeassignment::operator=(const Opeassignment& p){
        if (this != &p) {
            m_age = p.m_age;
            *m_score = *p.m_score; // 直接赋值
        }
        return *this;
    }
    
    Opeassignment::~Opeassignment() {}
    

    通过这些修改,你可以避免手动管理内存带来的问题,并且代码会更加简洁和安全。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月19日
  • 已采纳回答 2月11日
  • 创建了问题 2月11日