struct record
{
CString field[13];
};class Data
{
public:
record * rec;
Data *prec;
Data *next;
public:
Data()
{
rec=new record;
next=0;
prec=0;
}
~Data(){if(rec)delete rec;}
void Clear()
{
for(int a=0;a<13;a++)
{
rec->field[a]="";
}
}
void operator =(Data dat)
{
for(int a=0;a<13;a++)
rec->field[a]=dat.rec->field[a];
prec=dat.prec;
next=dat.next;
}
};在没有重载等号的时候没发现任何问题,当使用了重载后的等号后出现0xddddddcd内存不能为read
调试时发现等号执行后的结果和我预想的一样,出错是在 Clear 函数的 rec->field[a]="" 行。这就想不明白了,在没有重载等号或者不用重载的等号 Clear函数并没问题的.到底错在哪里?

解决方案 »

  1.   

    我想问题可能在这里,你把源码贴出来看看。
    rec->field[a]=dat.rec->field[a];
    string的=操作并不为新的string 对象分配内存
    比如
    string a="aaaaa0";
    string b;
    b=a;
    其实b和a共享同一块内存。
    当a不存在时你访问b就会出错。
      

  2.   

    struct record
    {
    CString field[13];
    };
    class Data
    {
    public:
    record * rec;
    Data *prec;
    Data *next;
    public:
    Data()
    {
    rec=new record;
    next=0;
    prec=0;
    }
    ~Data(){if(rec)delete rec;}
    void Clear()               //清除数据
    {
    for(int a=0;a<13;a++)
    {
    this->rec->field[a]="";
    }
    }
    void operator =(Data &dat)
    {
    for(int a=0;a<13;a++)
    rec->field[a]=dat.rec->field[a];
    prec=dat.prec;
    next=dat.next;
    }
    };
    class Grid
    //定义一个表,是个双链表组成的环.Data类是节点,有0--1000个节点.Data的成员rec指示真正的数据存放位置record结构
    //这个表用来存储由格式化好的文本文件中存储的数据,实现一些基本的数据库查找等操作.由于文件有很多个,总大小几十MB,所以做个这样的表,不一次把所有数据读入表中。但本人并没有这方面的经验
    {
    public:
    Data *hp;      //头节点,如果记录小于1000条等于head
    Data *cp;      //当前记录      
    Data *ep;      //尾节点
    Data *head;    //原始头节点,值不变
    Data temp;     //用来存储当前记录
    int count;     //表的大小
    public:
    Grid(void);
    ~Grid(void);
    int Serialize(char c);     //数据由这个函数存入表中
    int Append(void);          //向表中追加一个节点
    int UnAppend(void);
    int RecOK;
    int csp;
    CString GetCurrData(int x);
    int skip(int n=1);
    int GoTop(void);
    int GoBottom(void);
    int IsEnd(void);
    int stop;
    int pause;
    int Append0(void);     //当节点超过1000时此函数取代Append()被调用.我的问题出在这里,后面有这个函数的代码
    int UnAppend0(void);
    };int Grid::Append0(void)
    {
    Data j;
    stop=1;
    RecOK=0;
    csp=0;
    hp=hp->next;
    cp=cp->next;
    ep=ep->next; temp=*cp;         //这两行任意注释掉一行就看不出有问题,
    cp->Clear();      //实在不知道怎么回事 return 1;
    }int Grid::Append(void)
    {
    if(count==1000)return 0;
    Data *p=hp;
    if(p==0)
    {
    p=new Data;
    head=p;
    p->next=p;
    p->prec=p;
    hp=p;
    ep=p;
    cp=p;
    count++;
    }
    else
    {
    while(p->next!=hp)p=p->next;
    p->next=new Data;
    p->next->prec=p;
    p=p->next;
    p->next=hp;
    hp->prec=p;
    ep=p;
    cp=p;
    count++;
    }
    RecOK=0;
    csp=0;
    return 1;
    }int Grid::Serialize(char c)     //文本中每行一条记录,一条记录有13个字段,由TAB符分隔
                                    //其它类把数据从文件中读取并被送到这个函数
    {
    if(RecOK)
    {
    if(!Append())Append0();
    }
    switch(c)
    {
    case 9:
    csp++;
    break;
    case 13:
    RecOK=1;
    break;
    case 10:
    break;
    default:
    cp->rec->field[csp]+=c;
    }
    return 1;
    }前面的兄弟 zzw820626(dying)指出的问题确实是我事先没想到的,试了下真的是这样,才发现原来我并不了解CString类,可是我这个程序里用了CString类做主要的数据存储单元,实在让我愁。但这个程序是我急需的。各位帮帮我吧,感激不尽!
      

  3.   

    int Grid::Append0(void)
    {
    Data j;
    stop=1;
    RecOK=0;
    csp=0;
    hp=hp->next;
    cp=cp->next;
    ep=ep->next; temp=*cp;         //这两行任意注释掉一行就看不出有问题,
    cp->Clear();      //实在不知道怎么回事 return 1;
    }
    你的Append是什么意思?如果没有理解错误的话,你这个函数有问题。
    要添加一个节点,而你需要先分配一个空间来存贮新的节点,而你却没有这样做,只是把当前节点后的一个清空罢了
    cp=cp->next; 能保证cp不为空吗?
    根据理解,ep=ep->next;肯定会有问题,因为ep是最后一个了,其下一个肯定为空(NULL),等到下次再调用Append0时,这一句肯定出错
      

  4.   

    cp->next 和hp是相等的,这个链表是环状的
      

  5.   

    总算找出是怎么回事了,原来函数
    int Grid::Append0(void)
    {
           ...
    temp=*cp;         //这两行任意注释掉一行就看不出有问题,
    cp->Clear();      //实在不知道怎么回事
           ...
    }
    中temp=*p 行调用了重载的Data类等号
    void Data::operator =(Data dat)
    {
         for(int a=0;a<13;a++)
         rec->field[a]=dat.rec->field[a];
         prec=dat.prec;
         next=dat.next;
    }
    它的实参dat得到的只是个指针,在函数返回时dat被如下析构函数摧毁了
    ~Data()
    {
    if(rec)delete rec;
    }
    此时的rec指针所指的数据正是调用函数中cp->Clear()行中使用的.把类当作函数参数就和普通数据作为函数参数差不多看来只是我的一个错觉.
    可是新的问题又有了,因为Data类的析构函数必须这么写,但是在这个重载等号的函数中却需要它不释放rec所指的数据单元,该怎么办?
      

  6.   

    提一点改动:
    Data & operator =(const Data & dat)
    {
    *rec = *(dat.rec); //不需要你写循环,编译器产生的已经可以了
    prec=dat.prec;
    next=dat.next;
    return *this;
    }另外CString 和std::string并不是zzw820626所说的那样,这可不是java