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; } }
错误原因分析
- 野指针访问:
DoublySortedLinkedList构造函数中,m_pFirst和m_pLast是未初始化的指针,直接通过m_pFirst->data访问内存属于野指针解引用,触发内存访问错误。 - 头文件循环包含:
DoublyIterator.h和DoublySortedLinkedList.h互相包含,导致编译逻辑混乱。 - 宏定义冲突:
#define min和#define max会覆盖标准库中的同名宏,引发潜在编译问题。 - 类型初始化问题:
ItemType无默认构造函数,创建DoublyNodeType<ItemType>时,若未显式初始化data成员会编译失败。
修复方案
- 初始化指针并分配内存:在构造函数中为头尾节点分配内存,避免野指针访问。
- 解决循环依赖:移除
DoublyIterator.h中对DoublySortedLinkedList.h的包含,改用前向声明。 - 替换宏定义:用
const变量替代#define,避免和标准库冲突。 - 添加节点构造函数:给
DoublyNodeType添加带参数的构造函数,显式初始化data成员,适配无默认构造的类型。 - 添加析构函数:释放节点内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Yoony Lim
相关产品推荐
相关产品推荐

