2012-12-10 52 views
-2

所以我寫了一個簡單的哈希類,並使用Visual Studio環境時,我得到一個調試斷言錯誤「表達:字符串標超出範圍」然而,當我使用C++鏈接器的命令提示編譯並運行該程序運行正常。錯誤發生在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]: 
+1

斷言意味着你正在使用的約束外的一個指標。當它發生時,調試器應該中斷,讓你有機會觀察你的程序的狀態並找出你做錯了什麼。該斷言是一個用於調試的實用程序,並且僅在啓用迭代器調試時纔會引發(它可能不在您的命令行構建中)。 「這是我的程序,它已經壞了,請爲我調試」對Stack Overflow問題來說真的不合適。 –

+0

不檢查代碼注意,當使用調試器時,它會檢查更多在命令行中不會被注意的事情。你可能會破壞記憶,不太可能只是閱讀,但你可能正在閱讀垃圾,但你沒有注意到這樣一個簡單的程序。 – QuentinUK

回答

1

在partialHash功能可按,代碼[2]是外的邊界的訪問時代碼只包含 「一個」

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; 
    } 
+0

aaahhhh這是有道理的。似乎我需要確保字符串是2個字母或更多的我的哈希,對不對?爲什麼它在Visual Studio環境之外工作? – Painguy

+0

這是不確定的行爲來訪問外的boundry內存,你是幸運的,如果它不能在其他環境崩潰或不幸運的,因爲它不直接告訴錯誤。 – billz

+0

我認爲這樣做更有意義。感謝您的幫助,我真的很感激。 – Painguy