基于std::shared_ptr的C++模板类仅uint8_t实例化时触发段错误咨询
问题触发原因
- 你实现的
Array类默认构造函数中,为持有空指针的std::shared_ptr绑定了固定执行delete[]的删除器。C++标准明确规定delete[]空指针属于合法操作,不会触发异常,但你使用的gcc 9.2搭配gold链接器的版本存在特定bug:仅当对uint8_t/unsigned char类型的空指针执行delete[]时,会错误触发非法内存访问,其余内置类型的空指针delete[]操作不受影响。 - 代码中全局定义的
Array<uint8_t> Uint8实例、以及main函数作用域内的Array<uint8_t> pattern实例析构时,都会调用绑定的删除器执行delete[] nullptr,刚好命中上述bug,因此触发段错误,其余类型的实例不会触发。
修复方案
- 方案1:修改默认构造函数的删除器逻辑,增加空指针判断,规避非法操作:
Array() : m_size( 0 ) , m_array( nullptr, []( Type * p ){ if (p != nullptr) delete[] p; } ) {}
- 方案2:默认构造函数直接初始化空
shared_ptr,不绑定删除器,空shared_ptr析构时不会触发任何删除逻辑:
Array() : m_size( 0 ) , m_array() {}
- 优化建议:如果编译环境支持C++17及以上标准,可以直接使用
std::shared_ptr<Type[]>特化版本,原生支持数组析构时自动调用delete[],不需要手动编写删除器,代码可简化为:
template<class Type> class Array { size_t m_size; std::shared_ptr<Type[]> m_array; public: Array() : m_size( 0 ) , m_array() {} Array( const size_t size ) : m_size( size ) , m_array( new Type[size] {} ) {} Type & operator[]( const size_t & id ) { return m_array[id]; } const Type & operator[]( const size_t & id ) const { return m_array[id]; } // 其余原有get、size、赋值运算符逻辑可保持不变 };
内容的提问来源于stack exchange,提问作者Robert Ikanov
相关产品推荐
相关产品推荐

