C++ C++;;实例化一个类的多个实例会导致内存错误
以下是我的source.cpp:C++ C++;;实例化一个类的多个实例会导致内存错误,c++,memory,runtime-error,C++,Memory,Runtime 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();
#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;
}
您正在访问数据向量的越界索引。默认向量构造函数以大小0初始化(尽管它分配了2个额外元素),但随后您将立即尝试访问索引999:
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}
BST(){
对于(int i=0;i<1000;i++){
数据[i]=NULL;
}
}
第二个对象实际上与问题无关。即使只有一个对象,代码仍然在访问它不应该访问的内存
将数据向量更改为大小为1000的初始化将修复此特定代码的越界错误,但我怀疑BST类将来会导致更多此类错误,因为我看不到任何针对数据向量大小的检查。那么调试器说了什么?您认为谁会分配向量?顺便问一下,您不应该为树这样的数据结构使用向量连续分配的内存。@SemyonBurov有证据表明,向量更好的局部性和缓存友好性在很多常见的用例中都是成功的,即使其他数据结构对插入有更好的渐近保证。@Tim Seguine这不是常见的用例。二叉搜索树的结构正是由存储值的顺序决定的。若树的某个分支会超重,那个么向量将需要大量的内存,而且大部分都不会被使用。这是理解(inti=0;i<1000;i++){data.push_back(NULL);}的问题
#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
BST(){
for (int i = 0; i < 1000; i++){
data[i] = NULL;
}
}