拷贝复杂具体类型触发glibc断言错误,求错误原因及代码定位
错误原因分析
问题代码
#include "iostream" class Vector { private: double *elem; // elem points to an array of sz doubles int sz; public: Vector(int s); // constructor: establish invariant, acquire resources ~Vector() { delete[] elem; } // destructor: release resources Vector(const Vector &a); // copy constructor Vector &operator=(const Vector &a); // copy assignment double &operator[](int i) { return elem[i]; } }; Vector::Vector(const Vector &a) // copy constructor : elem{new double[sz]}, // allocate space for elements sz{a.sz} { for (int i = 0; i != sz; ++i) // copy elements elem[i] = a.elem[i]; } Vector &Vector::operator=(const Vector &a) // copy assignment { std::cout << "xxx" << std::endl; double *p = new double[a.sz]; for (int i = 0; i != a.sz; ++i) p[i] = a.elem[i]; delete[] elem; // delete old elements elem = p; sz = a.sz; return *this; } Vector::Vector(int s) :elem{new double[s]}, sz{s} { } int main() { Vector v1{4}; Vector v2 = v1; // copy v1’s representation into v2 v1[0] = 2; // v2[0] is now also 2! v2[1] = 3; std::cout << " success " << std::endl; }
运行错误信息
Fatal glibc error: malloc assertion failure in sysmalloc: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)
错误原因及问题代码定位
错误出在拷贝构造函数的初始化列表:
Vector::Vector(const Vector &a) : elem{new double[sz]}, // 此处sz未初始化,是随机垃圾值 sz{a.sz} { // ... }
C++中类成员的初始化顺序由类内部成员的声明顺序决定,而非初始化列表的书写顺序。Vector类先声明elem,再声明sz,所以初始化elem时,sz还未被赋值,是未定义的垃圾值。用这个随机值分配数组内存会引发两种问题:
- 分配的内存大小完全随机,可能远超系统可用内存,直接触发malloc的断言检查失败;
- 即使分配成功,后续拷贝元素的循环边界
sz是错误值,会导致数组越界访问,破坏堆内存结构,最终引发glibc的内存断言错误。
修复方法是调整初始化顺序,先初始化sz再分配elem内存:
Vector::Vector(const Vector &a) : sz{a.sz}, elem{new double[sz]} { for (int i = 0; i != sz; ++i) elem[i] = a.elem[i]; }
内容的提问来源于stack exchange,提问作者jurkDang
相关产品推荐
相关产品推荐

