project.exe 在 system("pause") 之后触发了一个断点

project.exe has triggered a breakpoint after system("pause")

我创建了自己的向量,当我尝试关闭驱动程序中的控制台时,我按下回车键并获得断点。

#include "MyVector.h"
#include <vector>

// Default constructor
MyVector::MyVector()
{
    theData = nullptr;
    vecSize = 0;
    vecCap = 0;
}

// Parameterized constructor
MyVector::MyVector(int vecCap)
{
    // Set vecSize to 0 and vecCap to user input (driver) plus 1 to account
    // for null terminator
    vecSize = 0;
    this->vecCap = vecCap;
    theData = new int[vecCap];
}

// Destructor
MyVector::~MyVector()
{
    // Run the clear() function
    clear();
}

// Copies the vector
void MyVector::copy(const MyVector& toCopy)
{
    // Set size and capacity to toCopy's
    this->vecCap = toCopy.vecCap;
    this->vecSize = toCopy.vecSize;

    // Create a temporary pointer array of ints
    int* tempArray = new int[];

    // Copy data from toCopy to new array
    for (int i = 0; i < toCopy.size(); i++)
    {
        tempArray[i] = toCopy.theData[i];
    }

    // Point theData to the tempArray
    theData = tempArray;
}

// Clears theData and resets vecCap and vecSize to 0
void MyVector::clear()
{
    // Check if theData is null
    if (theData != nullptr)
    {
        // Delete theData from heap and set to nullptr
        delete[] theData;
        theData = nullptr;

        // Set vecSize and vecCap to 0
        vecSize = 0;
        vecCap = 0;
    }
}

// Returns size of the vector
int MyVector::size() const
{
    return vecSize;
}

// Returns capacity of the vector
int MyVector::capacity() const
{
    return vecCap;
}

// Push input values into vector
void MyVector::push_back(int n)
{
    // Check if vecSize is too big for vecCap
    if (vecSize >= vecCap)
    {
        // Double vecCap through grow() function
        grow(vecCap);
    }

    // Set theData at element vecSize to user input n, increment vecSize
    theData[vecSize] = n;
    vecSize++;
}

// Returns index value of vector
int MyVector::at(int vecIdx) const
{
    // Check if vecIdx is within bounds
    if (vecIdx >= 0 && vecIdx <= vecSize)
    {
        // Return vector index
        return theData[vecIdx];
    }
    else
    {
        // Display out of bounds index
        throw vecIdx;
    }
}

// Doubles the size of the vector capacity
void MyVector::grow(int curCap)
{
    // Check if curCap is 0 ro less
    if (curCap <= 0)
    {
        // Set vecCap to CAP_GROWTH -1
        vecCap = CAP_GROWTH - 1;
    }
    else
    {
        // Increase curCap by CAP_GROWTH (doubled)
        vecCap = CAP_GROWTH * curCap;
    }

    // Create new array
    int* newArray = new int[vecCap];

    // Copy data to new array
    for (int idx = 0; idx < vecSize; idx++)
    {
        newArray[idx] = theData[idx];
    }

    // Delete theData
    delete[] theData;

    // Point theData to new array
    theData = newArray;
}

//
MyVector& MyVector::operator=(const MyVector& rho)
{
    // Check if the implicit object's address is the same as rho
    if (this != &rho)
    {
        // Clear the implicit object
        this->clear();
        // Copy the 
        this->copy(rho);
    }
    return *this;
}

// 
ostream& operator<<(ostream& out, const MyVector& rho)
{
    for (int idx = 0; idx < rho.size(); idx++)
    {
        // Output index of rho, separated by a space
        out << rho.at(idx) << " ";
    }
    return out;
}

我已经检查了某个地方,我可能试图重新删除一个指针,但我找不到任何东西,任何东西都没有说明抛出异常的原因。有什么建议吗?

在复制功能中,清除旧数据,根据容量创建新数据:

void MyVector::copy(const MyVector& x)
{
    clear();
    vecCap = x.vecCap;
    vecSize = x.vecSize;
    theData = new int[vecCap];

    for (int i = 0; i < x.size(); i++)
        theData[i] = x.theData[i];
}

此外,您在参数中使用了相同的名称,您这样做的方式并没有错,但使用不同的名称更容易:

MyVector::MyVector(int c)
{
    vecSize = 0;
    vecCap = c;
    theData = new int[vecCap];
}

你的class不符合规则3:

What is The Rule of Three?

您缺少复制构造函数。您的 copy 函数不是复制构造函数。您应该首先实现一个适当的复制构造函数。

此外,您的 copy 函数存在内存泄漏,因为您从未删除过旧数据。

这里有一个拷贝构造函数的例子

#include <algorithm>
//...
MyVector::MyVector(const MyVector& toCopy) : vecCap(toCopy.vecCap),
                                             vecSize(toCopy.vecSize),
                                             theData(new int[toCopy.capacity()])
{
    std::copy(toCopy.theData, toCopy.theData + toCopy.size(), theData);       
}

现在,如果你真的想保留 copy 函数(你真的不需要它,但为了参数你想保留它),你可以使用上面的复制构造函数:

// Copies the vector
void MyVector::copy(const MyVector& toCopy)
{
    MyVector temp(toCopy);  // calls the copy constructor
    std::swap(temp.vecCap, vecCap);
    std::swap(temp.vecSize, vecSize);
    std::swap(temp.theData, theData);
}

请注意,我们所做的只是创建一个临时副本,并将临时副本的数据替换为当前数据。当函数 return 与旧数据一起使用时,临时文件消失。

最后,您的赋值运算符可以使用您的 copy 函数编写。

MyVector& MyVector::operator=(const MyVector& rho)
{
    copy(rho);
    return *this;
}

所以从某种意义上说,您的 copy 函数是有目的的,如果唯一的目的是移动一些代码的话。

实际上,即使没有我建议的更改,这也是您应该为赋值运算符编写的代码。所有赋值运算符应该做的就是调用 copy 和 return 当前对象。