gpt4 book ai didi

c++ - 自定义 vector 类中的堆损坏错误

转载 作者:搜寻专家 更新时间:2023-10-31 00:56:47 24 4
gpt4 key购买 nike

我在编写的代码中收到运行时错误。当我调用 grow() 函数时,它运行良好,直到它点击 delete,然后它崩溃并显示:

Error I am getting

这让我很困惑,我不明白这是怎么回事。

这是我的代码发生的地方:

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

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

编辑:我根据建议更新了代码。

最佳答案

您的代码存在一些问题:

  1. 您的 MyVector(int) 构造函数没有分配请求数量的数组元素。它甚至根本没有触及 theVector,因此 theVector 正在成员初始化为 MINCAP 元素的默认值,即使请求的 cap 实际上更高。

  2. 您的 MyVector(MyVector&) 复制构造函数声明错误。要成为一个合适的复制构造函数,它需要通过 const 引用来获取输入对象。没有它,您就没有合适的复制构造函数。如果编译器生成自己的默认复制构造函数,它只会将您的 theVector 指针从一个对象复制到另一个对象,而不是实际创建数组数据的新拷贝,从而导致所有权问题。

  3. 恰当的例子,您的 printV() 函数接受一个输入 MyVector 按值,它复制构造一个临时对象.当临时对象超出范围并在其 theVector 指针上调用 delete[] 时,它实际上将销毁原始 MyVector 中的数组如果使用编译器的默认复制构造函数,则为对象。您需要一个合适的复制构造函数。

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

关于c++ - 自定义 vector 类中的堆损坏错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38800072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com