2011-07-07 115 views
1

我用C++編寫了一個程序,但在調試時遇到了一個問題,如果能在本代碼中幫助我,我會很高興。代碼和錯誤在下面被declaired:C++,Error,Native'已退出,代碼爲-1073741819(0xc0000005)

的錯誤是:

Unhandled exception at 0x011019d6 in 33.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd. 

的代碼是:

#include <iostream> 
#include <string> 
using namespace std; 
const int maxCard =100; 
//enum Boll {false, true}; 

class Contact 
{ 

public: 
    Contact (const char *name, const char *address, const char *tell); 
    //~ Contact(void); 
    const char* Name (void) const {return name;} 
    const char* Address (void) const {return address;} 
    const char* Tell (void) const {return tell;} 
    friend ostream& operator<< (ostream&, Contact&); 
private: 
    char *name; 
    char *address; 
    char *tell; 
}; 
class ContactDir 
{ 
public: 
    ContactDir(const int maxSize); 
    //~ContactDir(void); 
    void Insert(const Contact &); 
    void Delete(const char *name); 
    Contact* Find(const char *name); 
    friend ostream& operator <<(ostream&, ContactDir&); 
private: 
    int Lookup (const char *name); 
    Contact **contacts; 
    int dirSize; 
    int maxSize; 
}; 
Contact::Contact(const char *name, const char *address, const char *tell) 
{ 
    Contact::name= new char [strlen(name)+1]; 
    Contact::address= new char [strlen(address)+1]; 
    Contact::tell= new char [strlen(tell)+1]; 
    strcpy(Contact::name, name); 
    strcpy(Contact::address, address); 
    strcpy(Contact::tell,tell); 
} 
/*Contact::~Contact (void) 
{ 
    delete name; 
    delete address; 
    delete tell; 
}*/ 
ostream &operator<<(ostream &os, Contact &c) 
{ 
    os<<"("<<c.name<<","<<c.address<<","<<c.tell<< ")"; 
    return os; 
} 
ContactDir::ContactDir (const int max) 
{ 
    typedef Contact *ContactPtr; 
    dirSize=0; 
    maxSize=max; 
    contacts= new ContactPtr[maxSize]; 
}; 
/*ContactDir::~ContactDir (void) 
{ 
    for(register int i=0; i<dirSize; ++i) 
     delete contacts[i]; 
    delete []contacts; 
}*/ 
void ContactDir::Insert (const Contact& c) 
{ 
    if (dirSize<maxSize) 
    { 
     int idx= Lookup(c.Name()); 
     if(idx>0 &&strcmp(c.Name(), contacts[idx]->Name())==0) 
     { 
      delete contacts [idx]; 
     } 
     else 
     { 
      for (register int i=dirSize; i>idx; --i) 
       contacts[i]=contacts[i-1]; 
      ++dirSize; 
     } 
     contacts[idx]=new Contact (c.Name(),c.Address(),c.Tell()); 
    } 
} 
void ContactDir::Delete (const char *name) 
{ 
    int idx=Lookup(name); 
    if(idx<dirSize) 
    { 
     delete contacts[idx]; 
     --dirSize; 
     for (register int i=idx; i<dirSize; i++) 
      contacts[i]=contacts[i+1]; 
    } 
} 
Contact *ContactDir::Find (const char *name) 
{ 
    int idx= Lookup (name); 
    return (idx< dirSize && strcmp (contacts[idx]->Name(), name)==0)? contacts[idx]:0; 
} 
int ContactDir:: Lookup (const char *name) 
{ 
    for (register int i=0; i<dirSize; ++i) 
     if (strcmp (contacts[i]->Name(), name)==0) 
      return i; 
    return dirSize; 
} 

ostream &operator << (ostream &os, ContactDir &c) 
{ 
    for (register int i=0; i<c.dirSize; ++i) 
     os<< *(c.contacts[i]) << '\n'; 
    return os; 
} 

int main (void) 
{ 
    ContactDir dir (10); 
    dir.Insert(Contact ("JACK","NORWAY", "999999")); 
    dir.Insert(Contact ("JIMMY","FRANCE", "313131")); 
    cout<<dir; 

} 
+2

爲什麼'std :: string'存在時'const char *'無處不在? – vines

+2

您應該在調試器中運行該程序,它會告訴您發生訪問衝突的位置。(在源代碼中的哪一行) – sth

+1

每次在元素數量不確定的情況下都有最大元素數量時,該設計就是犯規。爲什麼不使用標準容器之一? –

回答

1

首先,你爲什麼不使用C++類字符串,例如std::string<string>?你可以避開醜陋的代碼是這樣的:

Contact::name= new char [strlen(name)+1]; 
Contact::address= new char [strlen(address)+1]; 
Contact::tell= new char [strlen(tell)+1]; 
strcpy(Contact::name, name); 
strcpy(Contact::address, address); 
strcpy(Contact::tell,tell); 

通過只輸入

Contact::Contact(const char *name, const char *address, const char *tell) : name(name), address(address), tell(tell) 

其中這些是在類中定義是這樣的:

std::string name, address, tell; 

其次,你爲什麼發明輪子再次?您可以簡單地使用位於<map>std::map,而不是創建自己的ContactDir課程。 Here是它的文檔。

下面的代碼實例化一個地圖,插入對象和檢索它們:

std::map<std::string, Contact> dir; 
dir["JACK"] = Contact("JACK","NORWAY", "999999")); 
dir["JIMMY"] = Contact ("JIMMY","FRANCE", "313131")); 

Object jimmy = dir["JIMMY"]; 

我知道,我沒有找到在段錯誤發生的確切位置,但我認爲這種做法將幫助你。

編輯:另外我覺得我發現你的問題。在Insert中,您進行Lookup調用,如果找不到該元素,則返回該調用的大小。但在Insert你永遠不會檢查值是否正確。我想是這樣...

2

首先,由於您使用的是C風格的字符串和相關功能(strlen等),你應該#include <cstring>,不<string> - 我的系統上,您的代碼不編譯。正如葡萄藤在評論中所說,無論如何,你最好用std::string。爲了找到你的問題,你應該在調試器中運行你的代碼。如果仍然無法確定錯誤發生的位置,請嘗試從代碼中反覆刪除功能並運行它以縮小問題的根源。

4

我同意關於實現的其他建議,但對於您的特定問題:Lookup函數返回dir的大小,如果它找不到要查找的內容。作爲索引,第二次插入將使用contacts[idx]->Name()中的值。 idx是1,但是在那個時候,數組的第二個單元沒有值。所以,當你撥打Name()時,你可以使用無效指針來調用它。您錯過了基於1的大小和基於0的索引之間的差異。

通常,0xcdcdcdcd是一個常見模式,由VS在調試版本中對未初始化的指針設置。

相關問題