繁体   English   中英

C++,错误,本机'已退出,代码为 -1073741819 (0xc0000005)

[英]C++, Error, Native' has exited with code -1073741819 (0xc0000005)

我在 C++ 中编写了一个程序,但在调试时遇到了问题,如果您能在此代码中帮助我,我将很高兴,代码的来源和错误已在以下内容中声明:

错误是:

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;

}

我同意 rest 关于实施的建议,但至于您的具体问题:如果找不到所需的内容,您Lookup function 返回 dir 的大小。 然后,您的第二个插入使用contacts[idx]->Name()中的该值作为索引。 idx为 1,但此时数组的第二个单元格中没有值。 因此,当您调用Name()时,您会在无效指针上调用它。 您已经忽略了基于 1 的大小和基于 0 的索引之间的区别。

一般来说,0xcdcdcdcd 是一种常见的模式,由 VS 在调试版本中对未初始化的指针设置。

首先,由于您使用的是 c 风格的字符串和相关的函数( strlen等),因此您应该#include <cstring>而不是<string> - 在我的系统上,您的代码无法编译。 正如 vines 在评论中所说,无论如何你最好使用std::string 要找到你的问题,你应该在调试器中运行你的代码,就像某事所说的那样。 如果您仍然无法确定错误的位置,请尝试反复从代码中删除功能并运行它以缩小问题的根源。

首先,为什么不对字符串使用 C++ 类,例如<string>中的std::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)

其中这些在 class 中定义,如下所示:

std::string name, address, tell;

其次,你为什么要再次发明轮子? 无需创建自己的ContactDir class,您只需使用位于<map>中的std::map 是它的文档。

以下代码实例化 map,插入对象并检索它们:

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中,您永远不会检查值是否正确。 我认同...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM