-2

所以我写了一个简单的 Hash 类,当使用 Visual Studio 环境时,我得到一个调试断言错误“表达式:字符串下标超出范围”但是当我在命令提示符下使用 c++ Linker 编译和运行程序时运行良好。错误发生在 h.add("a", "la");

这是代码

#include <iostream>
#include <string>
using namespace std;
bool die(const string &msg);

class Hash{
    public:
        Hash( unsigned tablesize, unsigned maxUsed );
        ~Hash();
        bool in( const string & code ) const;
        bool getDescription( string & description, const string & code ) const;
        void add( const string & code, const string & description );
        void changeDescription( const string & code, const string & newDescription );
        void showone(const string &code) const;
        void show() const;
    private:
        struct Data{
            string code;
            string descrip;
        };
        unsigned hash(unsigned val) const;
        unsigned rehash(unsigned val) const;
        static unsigned Hash::partialHash( const string & code );
        static bool prime( unsigned n );
        unsigned findindex(const string &code) const;
        Data *ptr;
        unsigned maxUsed;
        unsigned elements;
        unsigned tablesize;
        unsigned p;
        unsigned p2;
};

Hash::Hash(unsigned size, unsigned maxused){
    if(UINT_MAX-3<size || size<=4 || size<=maxused )
        die("Invalid Constructor");
    for(tablesize=size; !prime(tablesize); tablesize++){}
    ptr=new Data[tablesize];
    elements=0;
    maxUsed=maxused;
    for(p=tablesize; !prime(--p);){}
    for(p2=p; !prime(--p2);){}
    for(unsigned i=0; i<tablesize; i++){
        ptr[i].code="\0";
        ptr[i].descrip="\0";
    }
}

Hash::~Hash(){
    delete[] ptr;
}

bool Hash::in(const string &code)const{
    if(code==ptr[findindex(code)].code)
        return true;
    return false;
}

void Hash::showone(const string &code) const{
 unsigned i=findindex(code);
 cout<<'['<<i<<"]: "<<ptr[i].code<<' '<<ptr[i].descrip<<'\n';
}
void Hash::show() const{
 for(unsigned i=0; i<tablesize; i++)
  cout<<'['<<i<<"]: "<<ptr[i].code<<' '<<ptr[i].descrip<<'\n';
}

bool Hash::getDescription( string & description, const string & code ) const{
    if(in(code)){
        description=ptr[findindex(code)].descrip;
        return true;
    }
    return false;
}

void Hash::changeDescription(const string & code, const string & newdescription ){
    if(in(code)){
        ptr[findindex(code)].descrip=newdescription;
    }else{
        die("code not in table");
    }
}

unsigned Hash::hash(unsigned partialHashValue)const{
    return partialHashValue%p;
}

unsigned Hash::rehash(unsigned partialHashValue)const{
    return partialHashValue%p2+1;
}

unsigned Hash::partialHash( const string & code ){
    return (code[0]*26+code[1])*26+code[2];
}

void Hash::add( const string & code, const string & description ){
    if(in(code)) die("can't add");
    if(elements==maxUsed) die("Overflow");
    unsigned i=findindex(code);
    ptr[i].code=code;
    ptr[i].descrip=description;
    elements++;
}

bool Hash::prime( unsigned n ){
        if( n < 4 )  return n > 1;
        if( n%2 == 0 || n%3 == 0 )  return false;
        for(  unsigned fac = 5, inc = 4;  ;  fac += inc = 6-inc  ){
            if( fac > n/fac )  return true;
            if( n%fac == 0 )  return false;
        }   
    }

unsigned Hash::findindex( const string &code) const{
    unsigned partial=partialHash(code);
    unsigned hashnum = hash(partial);
    if(ptr[hashnum].code=="\0" || ptr[hashnum].code == code) return hashnum;
    unsigned rehashnum = rehash(partial);
    do{
        hashnum = (hashnum + rehashnum) % tablesize;
    }while(  ptr[hashnum].code != "\0" && ptr[hashnum].code != code );
    return hashnum;
}

int main(){
    Hash h(12, 8);
    h.add("LAX", "Space Shuttle Endeavour arrived here 9/21/2012");
    h.add("DEN", "jajaja");
    h.add("gold", "lalalala");
    h.add("Pp", "la");
    h.add("a", "la");
    h.add("b", "la");
    h.add("c", "la");
    h.add("d", "la");
    cout<<"p\n";
    h.showone("LAX");
    cout<<"\n\n";
    h.show();
}

bool die(string const &msg){
 cerr<<"fatal error: "<<msg;
 exit(EXIT_FAILURE);
}

这是输出

[0]: gold lalalala
[1]: DEN jajaja
[2]: LAX Space Shuttle Endeavour arrived here 9/21/2012
[3]:
[4]:
[5]: a la
[6]: b la
[7]: Pp la
[8]:
[9]: d la
[10]: c la
[11]:
[12]:
4

1 回答 1

1

在 partialHash 函数中,code[2] 在 code 只包含 "a" 时是越界访问

unsigned Hash::partialHash( const string & code ){
    return (code[0]*26+code[1])*26+code[2];
}

您可以使用 at() 函数并捕获抛出的异常

   unsigned Hash::partialHash( const string & code )
    {
        try {
          return (code.at(0)*26+code.at(1))*26+code.at(2);
        } 
        catch(std::exception& e){
          std::cout << e.what() << std::endl;
        }
        return 0;
    }
于 2012-12-10T00:08:40.747 回答