访问对象中的指针时内存读取错误

时间:2011-03-16 18:37:49

标签: c++

为了更好地理解,我将我的问题细分为不同的部分。它们如下:

A)课程我的问题与

有关

我有一个类TLst代表如下列表:

template <class TVal>
class TLst{
public:
  typedef TLstNd<TVal>* PLstNd;
private:
  int Nds;
  PLstNd FirstNd;
  PLstNd LastNd;
public:
  TLst(): Nds(0), FirstNd(NULL), LastNd(NULL){}
  TLst(const TLst&);
  ~TLst(){Clr();}
  explicit TLst(TSIn& SIn);
  void Save(TSOut& SOut) const;

**TLst <TVal>& operator = (const TLst <TVal> &t)
  {
    TLst<TVal>::PLstNd Nd;
    if (Len()!=t.Len()) { Clr(); }
    for (TLst<TVal>::PLstNd np = t.First(); np!=NULL ; np=np->Next()) {
        Nd = AddBack(np->GetVal()); 
    }
    return *this;
  }**

  void Clr(){
    PLstNd Nd=FirstNd;
    while (Nd!=NULL){PLstNd NextNd=Nd->NextNd; delete Nd; Nd=NextNd;}
    Nds=0; FirstNd=NULL; LastNd=NULL;}

  bool Empty() const {return Nds==0;}
  int Len() const {return Nds;}
  PLstNd First() const {return FirstNd;}
  PLstNd Last() const {return LastNd;}

**PLstNd AddBack(const TVal& Val){
    PLstNd Nd=new TLstNd<TVal>(LastNd, NULL, Val);
    if (LastNd!=NULL){LastNd->NextNd=Nd; LastNd=Nd;}
    else {FirstNd=Nd; LastNd=Nd;}
    Nds++; return Nd;
  }**

  PLstNd AddFrontSorted(const TVal& Val, const bool& Asc=true);
  PLstNd AddBackSorted(const TVal& Val, const bool& Asc=true);
  void PutFront(const PLstNd& Nd);
  void PutBack(const PLstNd& Nd);
  PLstNd Ins(const PLstNd& Nd, const TVal& Val);
  void Del(const TVal& Val);
  void Del(const PLstNd& Nd);

  PLstNd SearchForw(const TVal& Val);
  PLstNd SearchBack(const TVal& Val);

  friend class TLstNd<TVal>;
};

类似地,我有类TLstNd来表示列表节点,如下所示:

template <class TVal>
class TLstNd{
public:
  TLstNd* PrevNd;
  TLstNd* NextNd;
  TVal Val;
public:
  TLstNd(): PrevNd(NULL), NextNd(NULL), Val(){}
  TLstNd(const TLstNd&);
  **TLstNd(TLstNd* _PrevNd, TLstNd* _NextNd, const TVal& _Val):
    PrevNd(_PrevNd), NextNd(_NextNd), Val(_Val){}**

  TLstNd& operator=(const TLstNd&);

  TLstNd* Prev() const {Assert(this!=NULL); return PrevNd;}
  TLstNd* Next() const {Assert(this!=NULL); return NextNd;}
  TVal& GetVal(){Assert(this!=NULL); return Val;}
};

我有TVec类(不是整个班级)的成员和构造者,如下所示

template <class TVal>
class TVec{
public:
  typedef TVal* TIter;
protected:
  int MxVals; // if MxVals==-1, then ValT is not owned by us, we don't free it!
  int Vals;
  TVal* ValT;
  void Resize(const int& _MxVals=-1);
  TStr GetXOutOfBoundsErrMsg(const int& ValN) const;
public:
  TVec(): MxVals(0), Vals(0), ValT(NULL){}
  TVec(const TVec& Vec);
  **explicit TVec(const int& _Vals){
    IAssert(0<=_Vals); MxVals=Vals=_Vals;
    if (_Vals==0){ValT=NULL;} else {ValT=new TVal[_Vals];}}**
  TVec(const int& _MxVals, const int& _Vals){
    IAssert((0<=_Vals)&&(_Vals<=_MxVals)); MxVals=_MxVals; Vals=_Vals;
    if (_MxVals==0){ValT=NULL;} else {ValT=new TVal[_MxVals];}}
  explicit TVec(TVal *_ValT, const int& _Vals):
    MxVals(-1), Vals(_Vals), ValT(_ValT){}

...

};

我有TPair课程如下:

class TPair{
public:
  TVal1 Val1;
  TVal2 Val2;
public:
  TPair(): Val1(), Val2(){}
  TPair(const TPair& Pair): Val1(Pair.Val1), Val2(Pair.Val2){}
  **TPair(const TVal1& _Val1, const TVal2& _Val2): Val1(_Val1), Val2(_Val2){}**
...
  TPair& operator=(const TPair& Pair){
    if (this!=&Pair){Val1=Pair.Val1; Val2=Pair.Val2;} return *this;}
  bool operator==(const TPair& Pair) const {
    return (Val1==Pair.Val1)&&(Val2==Pair.Val2);}
...
};

B)我在做什么?

a)我有TVec&gt;&gt; class“typedef”-ed as

typedef TVec<TPair<TInt, TLst<TInt>>> TNdClass;

b)接下来,我创建一个TNdClass的对象,为

TNdClass UsrClassList(MXCLASS_SIZE); //calls TVec(const int& _Vals)

如果你看到加粗的TVec构造函数,上面的调用设置Vals,MxVals并为ValT分配MxVals内存,这意味着UsrClassList分配大小为MXCLASS_SIZE * sizeof(TPair&gt;)的内存。

c)接下来,我将Val1(类型为TInt)和Val2(类型为TLst)分配给两个变量NdCnt(类型为TInt)和节点(类型为TLst)。并声明TPair类型的变量NdClss&gt;如下:

TInt NdCnt(0);
TLst<TInt> Nodes;
NdCnt = UsrClassList[VecIdx].Val1; //assigning TInt to TInt
Nodes = UsrClassList[VecIdx].Val2; //assigning TLst<TInt> to TLst<TInt>
TPair<TInt, TLst<TInt> > NdClss; //declaration

d)接下来我使用TLst的AddBack函数向节点添加值为1的TInt(参见上面的粗体),并将用NdCnt和Nodes实例化的TPair对象分配给NdClassas:

Nodes->AddBack(1); //adding a TInt of value 1 to Nodes

e)最后,我创建了一个TPair类型的新对象,其中NdCnt和Nodes值作为参数,并分配给步骤c)中声明的NdClss变量(类型TPair)。

NdClss = TPair<TInt, TLst<TInt>>(NdCnt, Nodes); 

此步骤最终会出现内存读取错误的异常。

在代码的下方,当我调试Nodes.First() - &gt; NextNd或Nodes.First() - &gt; PrevNd的值时,编译器会给出“内存读取错误”,我觉得它表示NextNd和PrevNd指针没有分配内存。

当我调试代码时,我得到值'???'对于监视变量PrevNd和NextNd:

-       FirstNd 0x00e6b830 {PrevNd=0x00000000 NextNd=0x00000000 Val={...} } TLstNd<TInt> *
+       PrevNd  0x00000000 {PrevNd=??? NextNd=??? Val={...} }   TLstNd<TInt> *
+       NextNd  0x00000000 {PrevNd=??? NextNd=??? Val={...} }   TLstNd<TInt> *
+       Val {Val=0 Mn=-2147483648 Mx=2147483647 ...}    TInt
-       LastNd  0x00e6b830 {PrevNd=0x00000000 NextNd=0x00000000 Val={...} } TLstNd<TInt> *
+       PrevNd  0x00000000 {PrevNd=??? NextNd=??? Val={...} }   TLstNd<TInt> *
+       NextNd  0x00000000 {PrevNd=??? NextNd=??? Val={...} }   TLstNd<TInt> *
+       Val {Val=0 Mn=-2147483648 Mx=2147483647 ...}    TInt

为什么没有分配Nodes.First() - &gt; NextNd和Nodes.First() - &gt; PrevNd的内存的任何建议?我需要做些什么才能在TLst类中分配这两个指针的内存?

期待回复。

索姆纳特

1 个答案:

答案 0 :(得分:0)

我会尽力回答。但是在看完你的问题后,我的眼睛正在流血......

关于你的第一个问题:

我在代码中没有看到TLstNd :: PrevNd和TLstNd :: NextNd的分配。

并且您说访问这些成员后出现内存读取错误...

可能你应该分配它们......

关于你的第二个问题:

使用关键字 new 分配对象......