Wrapper类内存管理实现引发访问违例问题求助
问题分析与修复
你的Wrapper类存在多个关键逻辑错误,直接导致了访问违例,以下是具体问题和修复方案:
1. 带参构造函数逻辑完全错误
原代码中带参构造函数的判断逻辑完全颠倒,且未正确初始化指针:
Wrapper(const T& inner) { if (DataPtr != 0) DataPtr = inner.clone(); else DataPtr = 0; }
- 刚进入构造函数时,
DataPtr是未初始化的垃圾值,此时的if(DataPtr !=0)判断无意义,结果随机。 - 正确逻辑应该是直接克隆传入的对象,而非判断未初始化的指针:
Wrapper(const T& inner) : DataPtr(inner.clone()) {}
如果需要兼容inner.clone()返回null的场景,可改为:
Wrapper(const T& inner) { DataPtr = inner.clone(); }
2. 赋值运算符的两处致命错误
原赋值运算符存在参数错误和逻辑笔误:
Wrapper& operator=(Wrapper& original) { if (this != &original) { delete DataPtr; DataPtr = DataPtr = 0 ? 0 : original.DataPtr->clone(); } return *this; }
- 参数错误:赋值运算符的右值应设为
const引用,否则无法接收临时对象或const对象,正确参数为const Wrapper<T>& original。 - 逻辑笔误:
DataPtr = DataPtr = 0 ? ...是错误写法,应判断original.DataPtr是否为null,避免空指针调用clone():
Wrapper& operator=(const Wrapper<T>& original) { if (this != &original) { delete DataPtr; DataPtr = original.DataPtr ? original.DataPtr->clone() : nullptr; } return *this; }
3. 缺失拷贝构造函数
你实现了赋值运算符,但未定义拷贝构造函数。当Wrapper对象被拷贝(如传值、存入容器)时,默认拷贝构造函数会让多个对象共享同一个DataPtr,析构时重复delete会引发内存错误,需补充:
Wrapper(const Wrapper<T>& other) { DataPtr = other.DataPtr ? other.DataPtr->clone() : nullptr; }
4. 解引用/箭头运算符未做空指针检查
当DataPtr为null时,直接调用operator*()或operator->()会触发访问违例,可添加断言或空指针检查:
T& operator*() { assert(DataPtr != nullptr && "Wrapper holds a null pointer"); return *DataPtr; } T* operator->() { assert(DataPtr != nullptr && "Wrapper holds a null pointer"); return DataPtr; } // const版本同理补充检查 const T& operator*() const { assert(DataPtr != nullptr && "Wrapper holds a null pointer"); return *DataPtr; } const T* operator->() const { assert(DataPtr != nullptr && "Wrapper holds a null pointer"); return DataPtr; }
关于0xFFFFFFFFFFFFFFFF访问违例的原因
当DataPtr为nullptr(0)时,部分系统/编译器会将空指针解引用错误标记为访问0xFFFFFFFFFFFFFFFF,你的构造函数错误导致DataPtr被错误设为null或未初始化就被使用,最终触发了该异常。
内容的提问来源于stack exchange,提问作者Naji MEDIOUNI
相关产品推荐
相关产品推荐

