-8

我正在尝试为我的类实现 operator+(它必须连接来自同一类的两个对象的单链表),但程序给出错误:“lab5.exe 中 0x01351ca3 处的未处理异常:0xC0000005:访问冲突读取位置 0xcccccccc 。” 奇怪的是它正确连接,因为我在 operator+ 中返回 temp 之前正在检查它(通过 //temp.print();)。

如果您能解释一下我的错误在哪里,我将不胜感激。这是代码:

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

    class list{

    struct lista
    {
        int num;
        char* word;
        lista* next;
    };
    lista* head;
    char* name;
    public:
        list(char* name1){head=NULL;name=new char[strlen(name1)+1];strcpy(name,name1);}
        char getChar(int key, int index);
        void setChar(int key, int index, char c);
        void insert(int number,char* txt);
        void remove(int number);
        void print();
        list(const list &o);
        list& operator=(const list &x);
        list& operator+(list &x);
        ~list();
    };
    void list::insert(int number,char* txt){
        lista* ptr,*tmp;
            ptr=head;
        lista* newlista=new lista;
        newlista->num=number;
        newlista->next=NULL;
        newlista->word= new char[strlen(txt)+1];
        strcpy(newlista->word,txt);
        if(head==NULL){
            head=newlista;
            newlista->next=NULL;
        }
        else while(ptr!=NULL){
                if(strcmp(txt,ptr->word)>=0){
                    if(ptr->next!=NULL && strcmp(txt,ptr->next->word)<=0)
                {
                    tmp=ptr->next;
                    ptr->next=newlista;
                    newlista->next=tmp;
                    break;
                }
                    else if(ptr->next!=NULL && strcmp(txt,ptr->next->word)>0)
                        ptr=ptr->next;
                    else
                     {
                        //next is empty
                        ptr->next=newlista;
                        break;
                     }
        }
                else{
                    //txt less than in 1st element
                    newlista->next=head;
                    head=newlista;
                    break;
                }      
        }
        return;
    }

    void list::print(){
        cout<<name<<";"<<endl;
        lista *druk;
        druk=head;
        while(druk!=NULL){
            cout<<"txt: "<<druk->word<<" | "<<"num: "<<druk->num<<endl;
            druk=druk->next;
        }
        cout<<endl;
        return;
    }


    void list::remove(int number){
        if(head==NULL)
            return;
        if(head->num==number){
            lista* ptr=head;
            head=head->next;
            delete [] ptr->word;
            delete ptr;
            return;
        }
        lista* ptr=head;
        while(ptr->next!=NULL && ptr->next->num!=number)
            ptr=ptr->next;
        if(ptr->next==NULL){
            cout<<number<<" element not found"<<endl;
            return;
        }
        lista* todelete=ptr->next;
        ptr->next=todelete->next;
        delete [] todelete->word;
        delete todelete;
        return;
    }
    list::list(const list &o)
    {
        lista *xtr = o.head;
        head=NULL;// without it doesn't work.
        lista *etr=head;// set etr on head?
        while (xtr)
        {
    lista* ntr = new lista;
        if (!ntr)
            {
    cerr << "list::CopyConstructor: Allocation memory failure!";
    cerr << endl;
    break;
            }
    ntr->num = xtr->num;
    ntr->word= new char[strlen(xtr->word)+1];
    strcpy(ntr->word,xtr->word);
    ntr->next = NULL;
        if (head)
            etr->next = ntr;    
        else
            head = ntr;
    etr = ntr; // keep track of the last element in *this
    xtr = xtr->next;
        }
    name = new char[strlen(o.name)+5];
    strcpy(name,o.name);
    strcat(name,"Copy");
    }

    list& list::operator=(const list &x)
    {
        if(this==&x)
            return *this;
        lista *etr=head;
        while(etr) // removing list from this
        {
            etr=etr->next;
            delete head;
            head=etr;
        }
        lista *xtr=x.head;
        while(xtr)
        {
            int copied=xtr->num;
            lista *ntr= new lista;
            ntr->word=new char[strlen(xtr->word)+1];
            if (!ntr) 
                {
    cerr << "list::operator=: Allocation memory failure!" << endl;
    break;
                }
            ntr->num=copied;
            strcpy(ntr->word,xtr->word);
            ntr->next=NULL;
            if (!head)
                head = ntr;
            else
                etr->next = ntr;

                etr = ntr; // keep track of the last element in *this
                xtr = xtr->next;
    }
    char *name=new char[strlen(x.name)+1];
    strcpy(name,x.name);
    return *this;
    }

    list::~list()
    {
        cout<<"Object with name:"<<name<<" destroyed!"<<endl;
        delete [] name;
        lista *dtr=head;
        while(dtr) // removing lista from this
        {
            dtr=dtr->next;
            delete [] head->word;
            delete head;
            head=dtr;
        }

    }

    list& list::operator+(list &x)
    {
        list temp(this->name);
        temp=*this;// using previously made operator= which creates the deep copy of singly linked list from this into temp;
        lista *xtr=x.head;
        while(xtr)
        {
            temp.insert(xtr->num,xtr->word);
            xtr=xtr->next;
        }   
        //temp.print();
        return temp;
    }
    int main(){
        list l1("lista1");
        l1.insert(5,"Endian");
        l1.insert(7,"Endianness");
        l1.insert(100,"Hexediting");
        l1.insert(34,".mil");

        l1.print();
        list l2(l1); // usage of CC - the same as list l2=l1; 
        l2.print();
        l2.remove(5);
        l2.print();
        l1.print();

        list l3("asajnment");
            l3=l2=l1;
        l3.print();
        list l4("Testing+");
        l4.insert(155,"+++++++");
        l4.insert(144,"-----");
        l4.insert(111,"lalala");
        l4.print();
        l1=l4+l3;
        l1.print();
        getchar();
        return 0;
    }
4

2 回答 2

2

我认为您不应该在 operator+ 中返回参考

list list::operator+(list &x)
    {
        list temp(this->name);
        temp=*this;// using previously made operator= which creates the deep copy of singly linked list from this into temp;
        lista *xtr=x.head;
        while(xtr)
        {
            temp.insert(xtr->num,xtr->word);
            xtr=xtr->next;
        }   
        //temp.print();
        return temp;
    }

如果您想像评论中提到的那样返回链接参考:

list& list::operator+(list &x)
        {
            lista *xtr=x.head;
            while(xtr)
            {
                this->insert(xtr->num,xtr->word);
                xtr=xtr->next;
            }   
            return this;
        }

这会将x的值连接到您当前的对象。

您的编译器仍然应该警告您您正在返回对临时的引用。

此外,您应该开始接受更多的答案,并考虑观众在看到您的帖子时的想法,您认为您发布的内容是否格式良好、信息丰富等。

于 2012-04-22T20:24:01.627 回答
1

您正在返回对临时对象的引用。这是不正确的。

当它被外部代码使用时,引用的对象已经被销毁。

于 2012-04-22T20:53:16.023 回答