C++ 我的自定义向量有一个运行时错误调试断言失败:_CrtIsValidHeapPointer(块)
我的向量类的一部分C++ 我的自定义向量有一个运行时错误调试断言失败:_CrtIsValidHeapPointer(块),c++,visual-studio,C++,Visual Studio,我的向量类的一部分 class CVector { friend ostream &operator<<(ostream& output, const CVector& vec); public: CVector() { sPtr = new char[10]; size = 0; capacity = 10; } CVector(const CVector &
class CVector
{
friend ostream &operator<<(ostream& output, const CVector& vec);
public:
CVector()
{
sPtr = new char[10];
size = 0;
capacity = 10;
}
CVector(const CVector &vec)
{
size = vec.size;
capacity = vec.capacity;
sPtr = new char[size];
cout << "copy constructor" << endl;
for (size_t i = 0; i < size; i++)
{
sPtr[i] = vec.sPtr[i];
}
}
类CVector
{
friend ostream&operator在复制构造函数中,您分配向量大小
字节,但将容量
设置为向量容量
。您可能需要分配向量容量
字节
其次,复制构造和复制分配之间存在差异:
CVector vecb(veca); // this calls the copy constructor
CVector vecc; // this calls the default constructor
vecc = vecb; // this calls the copy assignment operator
由于尚未为复制赋值运算符提供实现,编译器将为您生成一个,如下所示:
CVector & operator = (const CVector & other) {
size = other.size;
capacity = other.capacity;
sPtr = other.sPtr;
}
这不适合你,因为
你失去了对sPtr的跟踪,没有人删除它
两个不同的CVector
现在通过sPtr
指向同一内存。当调用第一个CVector
的析构函数时,它将delete sPtr
。然后另一个CVector
将指向已经delete
d的内存。当它是析构函数(或任何其他成员函数)时调用时,它尝试删除
或访问删除
的内存
这就是规则3(或规则5,取决于是否实现移动语义)的原因
实现复制(和移动)赋值运算符的一种简单而好的方法是使用复制和交换习惯用法:
void swap(CVector & other) {
std::swap(size, other.size);
std::swap(capacity, other.capacity);
std::swap(sPtr, other.sPtr);
}
CVector & operator = (const CVector& other) {
CVector tmp(other); // make a copy of other
this->swap(other); // by swapping with other, tmp's destructor, will cleanup your previous sPtr
return *this;
}
多亏了你,我成功地完成了它。所提供的代码中没有使用复制构造函数。请提供push_back、复制赋值运算符和析构函数的完整定义。正如@Eljay提到的,语句vecc=vecb;
将调用复制赋值运算符,而不是复制构造函数。如果没有复制assig由于内部数组是通过引用进行复制的,因此此操作将失败。感谢您的回复,现在我知道复制构造函数用于Cvecc(vecb)
@benb我已将push\u函数放在上面
CVector & operator = (const CVector & other) {
size = other.size;
capacity = other.capacity;
sPtr = other.sPtr;
}
void swap(CVector & other) {
std::swap(size, other.size);
std::swap(capacity, other.capacity);
std::swap(sPtr, other.sPtr);
}
CVector & operator = (const CVector& other) {
CVector tmp(other); // make a copy of other
this->swap(other); // by swapping with other, tmp's destructor, will cleanup your previous sPtr
return *this;
}