我从我编写的代码中收到运行时错误。当我调用grow()
函数时,它会完美地运行,直到它到达delete
,然后崩溃并说:
这让我很困惑,我不明白这是怎么回事。
以下是我的代码:
.cpp文件
#include "MyVector.h"
#include <cstdlib>;
void MyVector::grow()
{
if (cap == 0)
cap = MINCAP;
else
cap = cap*MINCAP;
int* temp = new int[cap];
for (int i = 0; i < vectorSize; i++)
{
temp [i] = theVector[i];
}
for (int i = vectorSize; i < cap; i++)
{
temp[i] = 0;
}
delete[] theVector;
theVector = temp;
}
MyVector::MyVector()
{
clear();
}
MyVector::~MyVector()
{
delete[] this->theVector;
}
MyVector::MyVector(int _cap)
{
cap = _cap;
for (int i = 0; i < cap; i++)
{
this->theVector[i] = 0;
}
}
MyVector::MyVector(const MyVector & vect)
{
this->vectorSize = vect.vectorSize;
this->cap = vect.cap;
delete[] theVector;
theVector = new int[cap];
for (int i = 0; i < vectorSize; i++)
{
this->theVector[i] = vect.theVector[i];
}
for (int i = vectorSize; i < cap; i++)
{
this->theVector[i] = 0;
}
}
int MyVector::size() const
{
return vectorSize;
}
int MyVector::capacity() const
{
return cap;
}
void MyVector::clear()
{
vectorSize = 0;
cap = MINCAP;
delete[] theVector;
theVector = new int[MINCAP];
for (int i = 0; i <MINCAP; i++)
{
*(theVector + i) = 0;
}
}
//Put an int into the vector
void MyVector::push_back(int n)
{
if (theVector == nullptr)
clear();
if (vectorSize+1 >= cap)
{
grow();
theVector[vectorSize] = n;
vectorSize++;
}
else
{
theVector[vectorSize] = n;
vectorSize++;
}
}
int MyVector::at(int _location)
{
if (_location < 0 || _location >= vectorSize)
throw _location;
return theVector[_location];
}
MyVector & MyVector::operator=(const MyVector & rho)
{
// test for self assignment
if (this == &rho)
return *this;
// clean up array in left hand object (this)
delete[] this->theVector;
// create a new array big enough to hold right hand object's data
this->vectorSize = rho.size();
this->cap = rho.cap;
this->theVector = new int[cap];
// copy the data
for (int i = 0; i < vectorSize; i++)
{
this->theVector[i] = rho.theVector[i];
}
for (int i = vectorSize; i < cap; i++)
{
this->theVector[i] = 0;
}
// return this object
return *this;
}
The.h文件
#pragma once
#include <array>
#include <fstream>
using namespace std;
class MyVector
{
private:
//the minimum capacity of the vector
const int MINCAP = 2;
//the amount of items in the vector
int vectorSize = 0;
//the maximum ammount of items in the vector
int cap = MINCAP;
//The pointer to the first integer in the vector
int* theVector = new int[MINCAP];
//The grow function
//Parameters : none
//returns : none
void grow();
public:
//The nonparmeterized constructor
//Parameters : none
//returns :none
MyVector();
//The deconstructor
//Parameters : none
//returns : none
~MyVector();
// The parameterized constructor
//Parameters : the capacity to set it to
//returns : none
MyVector(int _cap);
//Get the size
//Parameters : none
//returns : the size
MyVector(const MyVector& vect);
//Get the size
//Parameters : none
//returns : the size
int size() const;
//get the capacity
//Parameters : none
//returns : cap
int capacity() const;
//clear the data
//Parameters : none
//returns :none
void clear();
//insert an int into the vector
//Parameters : the int
//returns : none
void push_back(int n);
//gets the int at a location
//Parameters : the location
//returns : the integer
int at(int _location);
//Overload the = operator
//Parameters : the one to copy
//returns : the vector
MyVector& operator=(const MyVector& rho);
//Overload the << operator
//Parameters : the one to copy
//returns : the vector
friend ostream& operator<<(ostream& os, MyVector& TheVector)
{
for (int i = 0; i < TheVector.size(); i++)
{
os << TheVector.at(i) << ", ";
}
return os;
}
};
测试它的驱动程序。
#include <iostream>
#include "MyVector.h"
using namespace std;
// the printV function
// used to test the copy constructor
// parameter: a MyVector object
void printV(MyVector);
int main()
{
cout << "\nCreating a vector Sam of size 4.";
MyVector sam(4);
cout << "\nPush 12 values into the vector.";
for (int i = 0; i < 12; i++)
sam.push_back(i);
cout << "\nHere is sam: ";
cout << sam;
cout << "\n---------------\n";
cout << "\nCreating a vector Joe of size 4.";
MyVector joe(4);
cout << "\nPush 6 values into the vector.";
for (int i = 0; i < 6; i++)
joe.push_back(i * 3);
cout << "\nHere is joe: ";
cout << joe;
cout << "\n---------------\n";
cout << "\nTest the overloaded assignment operator \"joe = sam\": ";
joe = sam;
cout << "\nHere is sam: ";
cout << sam;
cout << "\n---------------\n";
cout << "\nHere is joe: ";
cout << joe;
cout << "\n---------------\n";
// pass a copy of sam by value
printV(sam);
cout << endl;
system("PAUSE");
return 0;
}
void printV(MyVector v)
{
cout << "\n--------------------\n";
cout << "Printing a copy of a vector\n";
cout << v;
}
编辑:我用建议更新了代码。
答案 0 :(得分:4)
您的代码存在一些问题:
您的MyVector(int)
构造函数未分配所请求的数组元素数。它甚至根本没有触及theVector
,因此theVector
被成员初始化为默认的MINCAP
元素,即使请求的cap
实际上更高。
您的MyVector(MyVector&)
复制构造函数声明错误。要成为一个合适的拷贝构造函数,它需要通过 const 引用来获取输入对象。没有它,你没有适当的拷贝构造函数。如果编译器生成自己的默认复制构造函数,它只会将theVector
指针从一个对象复制到另一个对象,而不是实际创建数组数据的新副本,从而导致所有权问题。
例如,您的printV()
函数按值输入MyVector
,它复制构造一个临时对象。当临时超出范围并在其delete[]
指针上调用theVector
时,如果使用编译器的默认复制构造函数,它实际上将销毁原始MyVector
对象中的数组。你需要一个合适的拷贝构造函数。
clear()
正在使用delete
而不是delete[]
。分配有new
的内存必须以delete
释放。分配有new[]
的内存必须以delete[]
释放。它们不匹配会导致内存问题。
话虽如此,我建议以下实施:
#pragma once
#include <iostream>
class MyVector
{
private:
//the minimum capacity of the vector
const int MINCAP = 2;
//the number of items in the vector
int vectorSize = 0;
//the maximum number of items in the vector
int cap = 0;
//The pointer to the first integer in the vector
int* theVector = nullptr;
//The grow function
//Parameters : none
//returns : none
void grow();
public:
//The nonparmeterized constructor
//Parameters : none
//returns :none
MyVector();
// The parameterized constructor
//Parameters : the capacity to set it to
//returns : none
MyVector(int _cap);
// The copy constructor
//Parameters : the vector to copy from
//returns : none
MyVector(const MyVector& src);
// The move constructor
//Parameters : the vector to move from
//returns : none
MyVector(MyVector&& src);
//The destructor
//Parameters : none
//returns : none
~MyVector();
//Get the size
//Parameters : none
//returns : the size
int size() const;
//get the capacity
//Parameters : none
//returns : cap
int capacity() const;
//clear the data
//Parameters : none
//returns :none
void clear();
//insert an int into the vector
//Parameters : the int
//returns : none
void push_back(int n);
//gets the int at a location
//Parameters : the location
//returns : the integer
int at(int _location);
//swap the content of a vector with another
//Parameters : the vector to swap with
//returns : none
void swap(MyVector& other);
//Overload the copy = operator
//Parameters : the one to copy from
//returns : the vector
MyVector& operator=(const MyVector &rho);
//Overload the move = operator
//Parameters : the one to move from
//returns : the vector
MyVector& operator=(MyVector && rho);
//Overload the << operator
//Parameters : the one to print
//returns : the stream
friend std::ostream& operator<<(std::ostream& os, const MyVector& rho);
};
std::ostream& operator<<(std::ostream& os, const MyVector& rho);
void swap(MyVector &v1, MyVector &v2) { v1.swap(v2); }
namespace std {
template <>
void swap(MyVector &v1, MyVector &v2)
{
v1.swap(v2);
}
}
#include "MyVector.h"
#include <algorithm>
#include <utility>
MyVector::MyVector()
: MyVector(MINCAP)
{
}
MyVector::MyVector(int _cap)
: theVector(new int[_cap]), cap(_cap)
{
std::fill_n(theVector, cap, 0);
}
MyVector::MyVector(const MyVector & src)
: theVector(new int[src.cap]), cap(src.cap), vectorSize(src.vectorSize)
{
std::copy_n(src.theVector, vectorSize, theVector);
std::fill_n(theVector+vectorSize, cap-vectorSize, 0);
}
MyVector::MyVector(MyVector && src)
{
src.swap(*this);
}
MyVector::~MyVector()
{
delete[] theVector;
}
void MyVector::grow()
{
int newcap = cap;
if (newcap == 0)
newcap = MINCAP;
else
newcap = newcap * MINCAP;
int* newVector = new int[newcap];
std::copy_n(theVector, vectorSize, newVector);
std::fill_n(newVector+vectorSize, newcap-vectorSize, 0);
delete[] theVector;
theVector = newVector;
cap = newcap;
}
int MyVector::size() const
{
return vectorSize;
}
int MyVector::capacity() const
{
return cap;
}
void MyVector::clear()
{
*this = MyVector();
}
void MyVector::push_back(int n)
{
if (vectorSize >= cap)
grow();
theVector[vectorSize] = n;
++vectorSize;
}
int MyVector::at(int _location)
{
if ((_location < 0) || (_location >= vectorSize))
throw _location;
return theVector[_location];
}
void MyVector::swap(MyVector& other)
{
std::swap(theVector, other.theVector);
std::swap(cap, other.cap);
std::swap(vectorSize, other.vectorSize);
}
MyVector& MyVector::operator=(const MyVector &rho)
{
if (this != &rho)
{
int newcap = rho.cap;
if (cap != newcap)
{
delete[] theVector;
theVector = nullptr;
cap = 0;
vectorSize = 0;
theVector = new int[newcap];
cap = newcap;
}
int newsize = rho.vectorSize;
std::copy_n(rho.theVector, newsize, theVector);
std::fill_n(theVector+newsize, cap-newsize, 0);
vectorSize = newsize;
}
return *this;
}
MyVector& MyVector::operator=(MyVector && rho)
{
rho.swap(*this);
return *this;
}
std::ostream& operator<<(std::ostream& os, const MyVector& rho)
{
os << "size " << rho.vectorSize << ", capacity " << rho.cap;
if (rho.vectorSize > 0)
{
os << "\n" << rho.theVector[0];
for (int i = 1; i < rho.vectorSize; ++i)
{
os << ", " << rho.theVector[i];
}
}
return os;
}
#include <iostream>
#include "MyVector.h"
// the printV function
// used to test the copy constructor
// parameter: a MyVector object
void printV(MyVector);
int main()
{
std::cout << "\nCreating a vector Sam of capacity 4.";
MyVector sam(4);
std::cout << "\nPush 12 values into the vector.";
for (int i = 0; i < 12; ++i)
sam.push_back(i);
std::cout << "\nHere is sam: ";
std::cout << sam;
std::cout << "\n---------------\n";
std::cout << "\nCreating a vector Joe of capacity 4.";
MyVector joe(4);
std::cout << "\nPush 6 values into the vector.";
for (int i = 0; i < 6; ++i)
joe.push_back(i * 3);
std::cout << "\nHere is joe: ";
std::cout << joe;
std::cout << "\n---------------\n";
std::cout << "\nTest the overloaded copy assignment operator \"joe = sam\": ";
joe = sam;
std::cout << "\nHere is sam: ";
std::cout << sam;
std::cout << "\n---------------\n";
std::cout << "\nHere is joe: ";
std::cout << joe;
std::cout << "\n---------------\n";
std::cout << "\nTest the overloaded move assignment operator \"joe = MyVector(5)\": ";
joe = MyVector(5);
std::cout << "\nHere is joe: ";
std::cout << joe;
std::cout << "\n---------------\n";
// pass a copy of sam by value
printV(sam);
std::cout << std::endl;
system("PAUSE");
return 0;
}
void printV(MyVector v)
{
cout << "\n--------------------\n";
cout << "Printing a copy of a vector\n";
cout << v;
}