C++;实例化 class 的多个实例会导致内存错误
C++; instantiating multiple instances of a class results in memory error
这是我的 source.cpp:
#include "BST.h"
using namespace std;
int main(){
BST<int> test1;
BST<int> test2;
test1.insert(10);
test1.insert(15);
test1.insert(12);
test1.insert(14);
test1.insert(19);
test1.test();
cout << test1.contain(1) << endl;
cout << test1.isEmpty() << endl;
//cout << test2.isEmpty() << endl;
cin.get();
return 0;
}
这是我的头文件:
//Haris
#include <iostream>
#include "Vector.h"
template <typename Comparable>
class BST
{
public:
int size = 0;
int currentRootindex = 0;
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}
~BST(){
}
void insert(Comparable obj){
if (data[0] == NULL){
data[0] = obj;
size++;
}
else{
for (int index = 0; index < size; index++){
if (data[currentRootindex] < obj && data[(2 * currentRootindex) + 2] == NULL){
data[(2 * currentRootindex) + 2] = obj;
size++;
break;
}
else if (data[currentRootindex] >= obj && data[(2 * currentRootindex) + 1] == NULL){
data[(2 * currentRootindex) + 1] = obj;
size++;
break;
}
else if (data[currentRootindex] < obj){
currentRootindex = ((2 * currentRootindex) + 2);
}
else{
currentRootindex = ((2 * currentRootindex) + 1);
}
}
}
currentRootindex = 0;
}
bool isEmpty(){
if (data[0] == NULL){
return true;
}
else
return false;
}
bool contain(Comparable obj){
for (int index = 0; index < size; index++){
if (data[currentRootindex] < obj){
currentRootindex = ((2 * currentRootindex) + 2);
}
else if (data[currentRootindex] > obj){
currentRootindex = ((2 * currentRootindex) + 1);
}
else
return true;
}
return false;
}
void test(){
cout << data[5] << endl;
}
private:
Vector<Comparable> data;
};
如果我从 source.cpp 中注释掉 BST<int>test2
,代码将按预期运行。
但是当我在 BST<int>test1
之后实例化 BST<int>test2
时,我得到 Application Error: The memory could not be read
。我没有声明任何静态变量,因此 none 个变量在不同对象之间共享。
此外,我使用的 Vector 头文件是
#ifndef VECTOR_H
#define VECTOR_H
#include <algorithm>
#include <iostream>
template <typename Object>
class Vector
{
public:
explicit Vector( int initSize = 0 )
: theSize{ initSize }, theCapacity{ initSize + SPARE_CAPACITY }
{ objects = new Object[ theCapacity ]; }
Vector( const Vector & rhs )
: theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ nullptr }
{
objects = new Object[ theCapacity ];
for( int k = 0; k < theSize; ++k )
objects[ k ] = rhs.objects[ k ];
}
Vector & operator= ( const Vector & rhs )
{
Vector copy = rhs;
std::swap( *this, copy );
return *this;
}
~Vector( )
{ delete [ ] objects; }
Vector( Vector && rhs )
: theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }
{
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
Vector & operator= ( Vector && rhs )
{
std::swap( theSize, rhs.theSize );
std::swap( theCapacity, rhs.theCapacity );
std::swap( objects, rhs.objects );
return *this;
}
bool empty( ) const
{ return size( ) == 0; }
int size( ) const
{ return theSize; }
int capacity( ) const
{ return theCapacity; }
Object & operator[]( int index )
{
return objects[ index ];
}
const Object & operator[]( int index ) const
{
return objects[ index ];
}
void resize( int newSize )
{
if( newSize > theCapacity )
reserve( newSize * 2 );
theSize = newSize;
}
void reserve( int newCapacity )
{
if( newCapacity < theSize )
return;
Object *newArray = new Object[ newCapacity ];
for( int k = 0; k < theSize; ++k )
newArray[ k ] = std::move( objects[ k ] );
theCapacity = newCapacity;
std::swap( objects, newArray );
delete [ ] newArray;
}
// Stacky stuff
void push_back( const Object & x )
{
if( theSize == theCapacity )
reserve( 2 * theCapacity + 1 );
objects[ theSize++ ] = x;
}
// Stacky stuff
void push_back( Object && x )
{
if( theSize == theCapacity )
reserve( 2 * theCapacity + 1 );
objects[ theSize++ ] = std::move( x );
}
void pop_back( )
{
--theSize;
}
const Object & back ( ) const
{
return objects[ theSize - 1 ];
}
// Iterator stuff: not bounds checked
typedef Object * iterator;
typedef const Object * const_iterator;
iterator begin( )
{ return &objects[ 0 ]; }
const_iterator begin( ) const
{ return &objects[ 0 ]; }
iterator end( )
{ return &objects[ size( ) ]; }
const_iterator end( ) const
{ return &objects[ size( ) ]; }
static const int SPARE_CAPACITY = 2;
private:
int theSize;
int theCapacity;
Object * objects;
};
#endif
您正在访问数据向量的越界索引。默认向量构造函数初始化大小为 0(尽管它分配了 2 个额外元素),但随后您立即尝试访问索引 999:
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}
第二个对象与问题无关。即使只有一个对象,代码仍在访问它不应该访问的内存。
将数据向量更改为大小为 1000 的初始化修复了此特定代码的越界错误,但我怀疑 BST class 将来会导致更多此类错误,因为我看不到任何错误检查数据向量的大小。
这是我的 source.cpp:
#include "BST.h"
using namespace std;
int main(){
BST<int> test1;
BST<int> test2;
test1.insert(10);
test1.insert(15);
test1.insert(12);
test1.insert(14);
test1.insert(19);
test1.test();
cout << test1.contain(1) << endl;
cout << test1.isEmpty() << endl;
//cout << test2.isEmpty() << endl;
cin.get();
return 0;
}
这是我的头文件:
//Haris
#include <iostream>
#include "Vector.h"
template <typename Comparable>
class BST
{
public:
int size = 0;
int currentRootindex = 0;
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}
~BST(){
}
void insert(Comparable obj){
if (data[0] == NULL){
data[0] = obj;
size++;
}
else{
for (int index = 0; index < size; index++){
if (data[currentRootindex] < obj && data[(2 * currentRootindex) + 2] == NULL){
data[(2 * currentRootindex) + 2] = obj;
size++;
break;
}
else if (data[currentRootindex] >= obj && data[(2 * currentRootindex) + 1] == NULL){
data[(2 * currentRootindex) + 1] = obj;
size++;
break;
}
else if (data[currentRootindex] < obj){
currentRootindex = ((2 * currentRootindex) + 2);
}
else{
currentRootindex = ((2 * currentRootindex) + 1);
}
}
}
currentRootindex = 0;
}
bool isEmpty(){
if (data[0] == NULL){
return true;
}
else
return false;
}
bool contain(Comparable obj){
for (int index = 0; index < size; index++){
if (data[currentRootindex] < obj){
currentRootindex = ((2 * currentRootindex) + 2);
}
else if (data[currentRootindex] > obj){
currentRootindex = ((2 * currentRootindex) + 1);
}
else
return true;
}
return false;
}
void test(){
cout << data[5] << endl;
}
private:
Vector<Comparable> data;
};
如果我从 source.cpp 中注释掉 BST<int>test2
,代码将按预期运行。
但是当我在 BST<int>test1
之后实例化 BST<int>test2
时,我得到 Application Error: The memory could not be read
。我没有声明任何静态变量,因此 none 个变量在不同对象之间共享。
此外,我使用的 Vector 头文件是
#ifndef VECTOR_H
#define VECTOR_H
#include <algorithm>
#include <iostream>
template <typename Object>
class Vector
{
public:
explicit Vector( int initSize = 0 )
: theSize{ initSize }, theCapacity{ initSize + SPARE_CAPACITY }
{ objects = new Object[ theCapacity ]; }
Vector( const Vector & rhs )
: theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ nullptr }
{
objects = new Object[ theCapacity ];
for( int k = 0; k < theSize; ++k )
objects[ k ] = rhs.objects[ k ];
}
Vector & operator= ( const Vector & rhs )
{
Vector copy = rhs;
std::swap( *this, copy );
return *this;
}
~Vector( )
{ delete [ ] objects; }
Vector( Vector && rhs )
: theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }
{
rhs.objects = nullptr;
rhs.theSize = 0;
rhs.theCapacity = 0;
}
Vector & operator= ( Vector && rhs )
{
std::swap( theSize, rhs.theSize );
std::swap( theCapacity, rhs.theCapacity );
std::swap( objects, rhs.objects );
return *this;
}
bool empty( ) const
{ return size( ) == 0; }
int size( ) const
{ return theSize; }
int capacity( ) const
{ return theCapacity; }
Object & operator[]( int index )
{
return objects[ index ];
}
const Object & operator[]( int index ) const
{
return objects[ index ];
}
void resize( int newSize )
{
if( newSize > theCapacity )
reserve( newSize * 2 );
theSize = newSize;
}
void reserve( int newCapacity )
{
if( newCapacity < theSize )
return;
Object *newArray = new Object[ newCapacity ];
for( int k = 0; k < theSize; ++k )
newArray[ k ] = std::move( objects[ k ] );
theCapacity = newCapacity;
std::swap( objects, newArray );
delete [ ] newArray;
}
// Stacky stuff
void push_back( const Object & x )
{
if( theSize == theCapacity )
reserve( 2 * theCapacity + 1 );
objects[ theSize++ ] = x;
}
// Stacky stuff
void push_back( Object && x )
{
if( theSize == theCapacity )
reserve( 2 * theCapacity + 1 );
objects[ theSize++ ] = std::move( x );
}
void pop_back( )
{
--theSize;
}
const Object & back ( ) const
{
return objects[ theSize - 1 ];
}
// Iterator stuff: not bounds checked
typedef Object * iterator;
typedef const Object * const_iterator;
iterator begin( )
{ return &objects[ 0 ]; }
const_iterator begin( ) const
{ return &objects[ 0 ]; }
iterator end( )
{ return &objects[ size( ) ]; }
const_iterator end( ) const
{ return &objects[ size( ) ]; }
static const int SPARE_CAPACITY = 2;
private:
int theSize;
int theCapacity;
Object * objects;
};
#endif
您正在访问数据向量的越界索引。默认向量构造函数初始化大小为 0(尽管它分配了 2 个额外元素),但随后您立即尝试访问索引 999:
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}
第二个对象与问题无关。即使只有一个对象,代码仍在访问它不应该访问的内存。
将数据向量更改为大小为 1000 的初始化修复了此特定代码的越界错误,但我怀疑 BST class 将来会导致更多此类错误,因为我看不到任何错误检查数据向量的大小。