Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我的自定义向量有一个运行时错误调试断言失败:_CrtIsValidHeapPointer(块)_C++_Visual Studio - Fatal编程技术网

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;
    }