调试断言失败! C++ VS2012 - 模板 Class
Debug Assertion Failed! C++ VS2012 - Template Class
我正在做一个作业,我已经为 Vector 组合了一个模板 class,现在(根据作业)继承了它以使其成为可排序的。在 void SearchableVector<T>::add(T itemToAdd)
方法的最后它抛出一个 Debug Assertion Failed!
错误。错误全文如下:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...tudio 2012\Projects\COSC 1437\Program 10\Debug\Program 10.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
我环顾四周,发现这是一个非常常见的错误,通常与内存管理有关。经常在不适当的事情上打电话给 delete
。我一定是在做类似的事情,因为我收到了错误,但我找不到我做错了什么。如果您能帮我 and/or 指出正确的方向,我们将不胜感激。
Main.cpp
#include "SimpleVector.h"
#include "SearchableVector.h"
#include <stdlib.h>
#include <time.h>
void main()
{
srand (time(NULL));
SearchableVector<int> v(0);
for (int i = 0; i < 20; i++)
{
v.add(rand() % 20);
}
v.print();
}
SimpleVector.h
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
template<class T>
class SimpleVector {
public:
//Constructors
SimpleVector(); //default constructor, size 0
SimpleVector(int); //parameterized constructor with default size
SimpleVector(const SimpleVector& a); //copy constructor
~SimpleVector(); //destructor
T& operator[](int) const;
SimpleVector<T>& operator=(SimpleVector<T>);
const bool operator==(SimpleVector&) const;
void push_back(T);
T& pop_back();
T& getElement(int);
int getSize() const;
void print() const;
protected:
int size;
T* internalArray;
void SimpleVector<T>::swap(SimpleVector&);
};
template<class T>
SimpleVector<T>::SimpleVector()
{
size = 0;
internalArray = nullptr;
}
template<class T>
SimpleVector<T>::SimpleVector(int sizeOfArray)
{
if (sizeOfArray < 0) throw "SimpleVector size must not be less than 0";
internalArray = new T[sizeOfArray]();
size = sizeOfArray;
}
template<class T>
SimpleVector<T>::SimpleVector(const SimpleVector& vectorToCopy):size(vectorToCopy.getSize()), internalArray( new T[vectorToCopy.getSize()] )
{
for (int i = 0; i < size; i++)
internalArray[i] = vectorToCopy.internalArray[i];
}
template<class T>
SimpleVector<T>::~SimpleVector() {
//cout << "Destructor called" << std::endl;
delete[] internalArray;
}
template<class T>
T& SimpleVector<T>::operator[](int i) const {
if (i<0 || i>=size) throw "Vector::operator[] : index is out of range";
return internalArray[i];
}
template<class T>
SimpleVector<T>& SimpleVector<T>::operator=(SimpleVector<T> rightSide) {
rightSide.swap(*this);
return *this;
}
template<class T>
const bool SimpleVector<T>::operator==(SimpleVector& right) const {
if (size() != right.size())
return false;
else {
for (int i = 0; i < size(); i++){
if (internalArray[i] != right[i])
return false;
}
}
return true;
}
template<class T>
void SimpleVector<T>::push_back(T itemToAdd) {
SimpleVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
temp[size] = itemToAdd;
temp.swap(*this);
}
template<class T>
T& SimpleVector<T>::pop_back()
{
SimpleVector<T> temp(size - 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
T pop = internalArray[size-a];
temp.swap(*this);
return pop;
}
template<class T>
T& SimpleVector<T>::getElement(int indexToGet)
{
return internalArray[indexToGet];
}
template<class T>
int SimpleVector<T>::getSize() const {
return this->size;
}
template<class T>
void SimpleVector<T>::print() const
{
for (int i = 0; i < size; i++)
{
std::cout << internalArray[i];
if (i!=(size-1))
std::cout << ",";
else
std::cout << std::endl;
if (i%10 == 0 && i!=0)
std::cout <<std::endl;
}
}
template<class T>
void SimpleVector<T>::swap(SimpleVector& other)
{
std::swap(internalArray, other.internalArray);
std::swap(size, other.size);
}
#endif
SearchableVector.h
#ifndef SEARCHABLEVECTOR_H
#define SEARCHABLEVECTOR_H
#include "SimpleVector.h"
template<class T>
class SearchableVector : protected SimpleVector<T>
{
public:
SearchableVector(int);
SearchableVector(const SearchableVector&);
~SearchableVector();
void add(T);
T getElement(int);
int getSize() const;
void print() const;
int search(T);
};
template<class T>
SearchableVector<T>::SearchableVector(int sizeOfArray) : SimpleVector(sizeOfArray)
{
}
template<class T>
SearchableVector<T>::SearchableVector(const SearchableVector& vectorToCopy) : SimpleVector(vectorToCopy)
{
}
template<class T>
SearchableVector<T>::~SearchableVector()
{
delete[] internalArray;
}
template<class T>
void SearchableVector<T>::add(T itemToAdd)
{
bool flag = false;
SearchableVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
{
if ((itemToAdd <= internalArray[i]) && (flag == false))
{
temp[i] = itemToAdd;
i++;
flag = true;
}
temp[i] = internalArray[i];
}
if (flag == false)
temp[size] = itemToAdd;
temp.swap(*this);
} // !*******************! THROWS THE ERROR RIGHT HERE !*******************!
template<class T>
T SearchableVector<T>::getElement(int elementToGet)
{
return SimpleVector::getElement(elementToGet);
}
template<class T>
int SearchableVector<T>::getSize() const
{
return SimpleVector::getSize();
}
template<class T>
void SearchableVector<T>::print() const
{
SimpleVector::print();
}
template<class T>
int SearchableVector<T>::search(T itemToSearchFor)
{
}
#endif
首先,在使用继承的时候,99%的时候应该使用虚析构函数。
这很重要。
virtual ~SimpleVector();
当删除一个对象时,它的基础 class 析构函数也会被调用。
在您的情况下,两个析构函数中都有 delete[] internalArray;
。
把删除留在基class,因为那个成员属于它,它应该处理它。
下次遇到类似情况时,在该对象类型的所有 delete
调用附近放置一个断点,然后您就可以看到调用了哪些以及调用的顺序。
我正在做一个作业,我已经为 Vector 组合了一个模板 class,现在(根据作业)继承了它以使其成为可排序的。在 void SearchableVector<T>::add(T itemToAdd)
方法的最后它抛出一个 Debug Assertion Failed!
错误。错误全文如下:
---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...tudio 2012\Projects\COSC 1437\Program 10\Debug\Program 10.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
我环顾四周,发现这是一个非常常见的错误,通常与内存管理有关。经常在不适当的事情上打电话给 delete
。我一定是在做类似的事情,因为我收到了错误,但我找不到我做错了什么。如果您能帮我 and/or 指出正确的方向,我们将不胜感激。
Main.cpp
#include "SimpleVector.h"
#include "SearchableVector.h"
#include <stdlib.h>
#include <time.h>
void main()
{
srand (time(NULL));
SearchableVector<int> v(0);
for (int i = 0; i < 20; i++)
{
v.add(rand() % 20);
}
v.print();
}
SimpleVector.h
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <stdexcept>
#include <iomanip>
using namespace std;
template<class T>
class SimpleVector {
public:
//Constructors
SimpleVector(); //default constructor, size 0
SimpleVector(int); //parameterized constructor with default size
SimpleVector(const SimpleVector& a); //copy constructor
~SimpleVector(); //destructor
T& operator[](int) const;
SimpleVector<T>& operator=(SimpleVector<T>);
const bool operator==(SimpleVector&) const;
void push_back(T);
T& pop_back();
T& getElement(int);
int getSize() const;
void print() const;
protected:
int size;
T* internalArray;
void SimpleVector<T>::swap(SimpleVector&);
};
template<class T>
SimpleVector<T>::SimpleVector()
{
size = 0;
internalArray = nullptr;
}
template<class T>
SimpleVector<T>::SimpleVector(int sizeOfArray)
{
if (sizeOfArray < 0) throw "SimpleVector size must not be less than 0";
internalArray = new T[sizeOfArray]();
size = sizeOfArray;
}
template<class T>
SimpleVector<T>::SimpleVector(const SimpleVector& vectorToCopy):size(vectorToCopy.getSize()), internalArray( new T[vectorToCopy.getSize()] )
{
for (int i = 0; i < size; i++)
internalArray[i] = vectorToCopy.internalArray[i];
}
template<class T>
SimpleVector<T>::~SimpleVector() {
//cout << "Destructor called" << std::endl;
delete[] internalArray;
}
template<class T>
T& SimpleVector<T>::operator[](int i) const {
if (i<0 || i>=size) throw "Vector::operator[] : index is out of range";
return internalArray[i];
}
template<class T>
SimpleVector<T>& SimpleVector<T>::operator=(SimpleVector<T> rightSide) {
rightSide.swap(*this);
return *this;
}
template<class T>
const bool SimpleVector<T>::operator==(SimpleVector& right) const {
if (size() != right.size())
return false;
else {
for (int i = 0; i < size(); i++){
if (internalArray[i] != right[i])
return false;
}
}
return true;
}
template<class T>
void SimpleVector<T>::push_back(T itemToAdd) {
SimpleVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
temp[size] = itemToAdd;
temp.swap(*this);
}
template<class T>
T& SimpleVector<T>::pop_back()
{
SimpleVector<T> temp(size - 1);
for (int i = 0; i < size; i++)
temp[i] = internalArray[i];
T pop = internalArray[size-a];
temp.swap(*this);
return pop;
}
template<class T>
T& SimpleVector<T>::getElement(int indexToGet)
{
return internalArray[indexToGet];
}
template<class T>
int SimpleVector<T>::getSize() const {
return this->size;
}
template<class T>
void SimpleVector<T>::print() const
{
for (int i = 0; i < size; i++)
{
std::cout << internalArray[i];
if (i!=(size-1))
std::cout << ",";
else
std::cout << std::endl;
if (i%10 == 0 && i!=0)
std::cout <<std::endl;
}
}
template<class T>
void SimpleVector<T>::swap(SimpleVector& other)
{
std::swap(internalArray, other.internalArray);
std::swap(size, other.size);
}
#endif
SearchableVector.h
#ifndef SEARCHABLEVECTOR_H
#define SEARCHABLEVECTOR_H
#include "SimpleVector.h"
template<class T>
class SearchableVector : protected SimpleVector<T>
{
public:
SearchableVector(int);
SearchableVector(const SearchableVector&);
~SearchableVector();
void add(T);
T getElement(int);
int getSize() const;
void print() const;
int search(T);
};
template<class T>
SearchableVector<T>::SearchableVector(int sizeOfArray) : SimpleVector(sizeOfArray)
{
}
template<class T>
SearchableVector<T>::SearchableVector(const SearchableVector& vectorToCopy) : SimpleVector(vectorToCopy)
{
}
template<class T>
SearchableVector<T>::~SearchableVector()
{
delete[] internalArray;
}
template<class T>
void SearchableVector<T>::add(T itemToAdd)
{
bool flag = false;
SearchableVector<T> temp(size + 1);
for (int i = 0; i < size; i++)
{
if ((itemToAdd <= internalArray[i]) && (flag == false))
{
temp[i] = itemToAdd;
i++;
flag = true;
}
temp[i] = internalArray[i];
}
if (flag == false)
temp[size] = itemToAdd;
temp.swap(*this);
} // !*******************! THROWS THE ERROR RIGHT HERE !*******************!
template<class T>
T SearchableVector<T>::getElement(int elementToGet)
{
return SimpleVector::getElement(elementToGet);
}
template<class T>
int SearchableVector<T>::getSize() const
{
return SimpleVector::getSize();
}
template<class T>
void SearchableVector<T>::print() const
{
SimpleVector::print();
}
template<class T>
int SearchableVector<T>::search(T itemToSearchFor)
{
}
#endif
首先,在使用继承的时候,99%的时候应该使用虚析构函数。
这很重要。
virtual ~SimpleVector();
当删除一个对象时,它的基础 class 析构函数也会被调用。
在您的情况下,两个析构函数中都有 delete[] internalArray;
。
把删除留在基class,因为那个成员属于它,它应该处理它。
下次遇到类似情况时,在该对象类型的所有 delete
调用附近放置一个断点,然后您就可以看到调用了哪些以及调用的顺序。