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 当前对象。
我创建了自己的向量,当我尝试关闭驱动程序中的控制台时,我按下回车键并获得断点。
#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 当前对象。