You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++拷贝构造函数出现空指针解引用错误,求问题原因

深拷贝浅拷贝代码中的空指针解引用问题

问题描述

许久未接触C++,为备战面试复习深拷贝与浅拷贝概念,编写了如下代码,运行时出现警告错误:Dereferencing NULL pointer uivar,位置为拷贝构造函数中的*(uivar) = *(mCopy.uivar);语句,请问问题出在哪里?

代码示例

#include <iostream>

class MyClass {
public:
    unsigned int* uivar = nullptr;

    MyClass() : uivar(new unsigned int) {
        *(this->uivar) = 3;
    }

    ~MyClass() { delete uivar; }

    MyClass(const MyClass& mCopy) {
        *(uivar) = *(mCopy.uivar);
    }
};

void function(MyClass m) {
    *(m.uivar) = 4;
}

int main() {
    MyClass myClass;
    MyClass myClassCopy = myClass;
    std::cout << *(myClass.uivar) << "\n";
    std::cout << *(myClassCopy.uivar) << "\n";
    function(myClass);
    std::cout << *(myClass.uivar) << "\n";
    std::cout << "hhhh" << "\n";
    *(myClassCopy.uivar) = 5;
    std::cout << *(myClass.uivar) << "\n";
    return 0;
}

问题分析与解决方案

核心问题:空指针解引用

你的拷贝构造函数中,uivar的默认初始化值是nullptr,但你直接对它进行解引用操作*(uivar) = ...——空指针不指向任何有效的内存地址,解引用空指针是未定义行为,这就是编译器警告的直接原因。

正确的深拷贝实现

要实现深拷贝,拷贝构造函数需要先为新对象的uivar分配独立的内存空间,再将源对象的值拷贝到这块新内存中,修改后的拷贝构造函数如下:

MyClass(const MyClass& mCopy) : uivar(new unsigned int) {
    *(this->uivar) = *(mCopy.uivar);
}

额外需要修复的问题

  • 缺失赋值运算符重载:当前代码只重写了拷贝构造函数,但没有重载赋值运算符operator=。当出现myClassCopy = myClass;这类赋值操作时,会调用默认的赋值运算符,导致浅拷贝——两个对象的uivar指向同一块内存,析构时会重复释放同一块内存,引发崩溃。需要补充赋值运算符重载:
MyClass& operator=(const MyClass& mCopy) {
    if (this != &mCopy) { // 防止自赋值
        delete uivar; // 释放当前对象已有的内存
        uivar = new unsigned int;
        *uivar = *mCopy.uivar;
    }
    return *this;
}
  • 传值调用的拷贝问题:function(MyClass m)是传值调用,会触发拷贝构造函数。如果拷贝构造函数未正确实现,不仅会出现空指针问题,还会导致临时对象和原对象共享内存,临时对象析构时释放内存后,原对象的uivar会变成悬空指针,后续访问会出错。

内容的提问来源于stack exchange,提问作者kesarling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:01:22