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

C++重载operator=后出现EXC_BAD_ACCESS错误求助

问题排查:EXC_BAD_ACCESS错误在ItemType::SetName调用时触发

此前修复了operator=重载错误,但现在调用ItemType的SetName时出现EXC_BAD_ACCESS (code=2, address=[address])错误,调试定位到DoublySortedLinkedList构造函数中给m_pFirst->data赋值min的位置。

最小复现代码

main.cpp

#include "DoublySortedLinkedList.h"

int main() {
    DoublySortedLinkedList<ItemType> m_List;
}

ItemType.h

#include <string>

using namespace std;

class ItemType {
public:
    ItemType(int Id) {
        m_Id = Id;
        m_sName = "";
    }

    int GetId() const {
        return m_Id;
    }

    string GetName() const
    {
        return m_sName;
    }

    void SetName(const string &inName) {
        m_sName = inName;
    }

    void SetId(int inId) {
        m_Id = inId;
    }

    ItemType& operator=(ItemType const &data) {
        this->SetName(data.GetName());
        this->SetId(data.GetId());
        return *this;
    }
protected:
    int m_Id;
    string m_sName; 
};

DoublyIterator.h

// 移除循环包含,改用前向声明
template<typename T>
struct DoublyNodeType;
template<typename T>
class DoublySortedLinkedList;

template <typename T>
class DoublyIterator
{
    friend class DoublySortedLinkedList<T>;
public:
    DoublyIterator(const DoublySortedLinkedList<T>& list) : m_List(list), m_pCurPointer(list.m_pFirst) {};
    T Next();
private:
    const DoublySortedLinkedList<T>& m_List;
    DoublyNodeType<T>* m_pCurPointer;
};

template <typename T>
T DoublyIterator<T>::Next() {
    m_pCurPointer = m_pCurPointer->next;
    return m_pCurPointer->data;
}

DoublySortedLinkedList.h

#include "ItemType.h"
#include "DoublyIterator.h"
#include <climits>

// 替换宏定义,避免和标准库冲突
const ItemType min_item(INT_MIN);
const ItemType max_item(INT_MAX);

template<typename T>
class DoublyIterator;

template <typename T>
struct DoublyNodeType
{
    T data;
    DoublyNodeType* prev;
    DoublyNodeType* next;
    // 添加构造函数,适配无默认构造的类型
    DoublyNodeType(const T& val) : data(val), prev(nullptr), next(nullptr) {}
};

template <typename T>
class DoublySortedLinkedList
{
    friend class DoublyIterator<T>;
public:
    DoublySortedLinkedList();
    // 添加析构函数避免内存泄漏
    ~DoublySortedLinkedList();
private:
    DoublyNodeType<T>* m_pFirst;
    DoublyNodeType<T>* m_pLast;
    int m_nLength;
};

template <typename T>
DoublySortedLinkedList<T>::DoublySortedLinkedList() {
    // 为头尾节点分配内存并初始化
    m_pFirst = new DoublyNodeType<T>(min_item);
    m_pLast = new DoublyNodeType<T>(max_item);
    // 连接头尾节点
    m_pFirst->next = m_pLast;
    m_pLast->prev = m_pFirst;
    m_nLength = 0;
}

template <typename T>
DoublySortedLinkedList<T>::~DoublySortedLinkedList() {
    // 释放所有节点内存
    DoublyNodeType<T>* current = m_pFirst;
    while (current != nullptr) {
        DoublyNodeType<T>* next = current->next;
        delete current;
        current = next;
    }
}

错误原因分析

  1. 野指针访问:DoublySortedLinkedList构造函数中,m_pFirst和m_pLast是未初始化的指针,直接通过m_pFirst->data访问内存属于野指针解引用,触发内存访问错误。
  2. 头文件循环包含:DoublyIterator.h和DoublySortedLinkedList.h互相包含,导致编译逻辑混乱。
  3. 宏定义冲突:#define min和#define max会覆盖标准库中的同名宏,引发潜在编译问题。
  4. 类型初始化问题:ItemType无默认构造函数,创建DoublyNodeType<ItemType>时,若未显式初始化data成员会编译失败。

修复方案

  1. 初始化指针并分配内存:在构造函数中为头尾节点分配内存,避免野指针访问。
  2. 解决循环依赖:移除DoublyIterator.h中对DoublySortedLinkedList.h的包含,改用前向声明。
  3. 替换宏定义:用const变量替代#define,避免和标准库冲突。
  4. 添加节点构造函数:给DoublyNodeType添加带参数的构造函数,显式初始化data成员,适配无默认构造的类型。
  5. 添加析构函数:释放节点内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:44:56