我用一个结构体保存了一个LPCTSTR的变量,我用new TCHAR[XX];赋给了哪个变量,然后我把这个结构体放到一个CList中,用完后我用delete 哪个我分配的内存时出错:Debug Error!
program:.......
DAMAGE:after normal block(#86) at xxxxxxxx.
我不知道那里出错了。

解决方案 »

  1.   

    你的描述好像有问题。LPCSTR是const char *,对这样的变量执行delete编译应该通不过才对。贴一下你的代码吧。应该使用LPTSTR什么的。
      

  2.   

    好像确实有问题,将LPCTSTR换成TCHAR *看看。
      

  3.   

    我说错了,我用的是LPTSTR。就是我有一个STRUCT中有几个LPTSTR变量(没有用CString的原因是它在UNICODE下工作不良)。
    大概代码如下:
    struct tagInfo
    {
    LPTSTR name;
    DWORD id;
    }Info,*pInfo;
    CList<Info,&Info> infoList;
    Info myInfo;
    myInfo.id =1000;
    infoList.AddTail(myInfo);
    name=new TCHAR[lstrlen(myname)];//my name is a string which define in my project
    ...
    // work out my work
    POSITION pos=infoList.GetHeadPosition();
    while(pos!=NULL)
    {
    POSITION nowpos=pos;
    Info *thisInfo=&infoList.GetNext(pos);
    if(thisInfo.id==1000)
    {
    TCHAR * tx=thiInfo.name;
    thisInfo.name=NULL;
    lstrcpy(toutname,tx);
    delete[] tx;//error here!error here!error here!!!!
    ....
    thisInfo.RemoveAt(nowpos);
    }
    }
    原代码太长,写这段大概可以表达我的意思。我是不想自己写连表,clist的原代码部分有点看不懂,谁看的懂的给我解释一下AddTail函数时CList构造对象的过程,谢谢。
      

  4.   

    TCHAR* tx is a pointer rather than a pointer array
    so you should use
    delete tx;
      

  5.   

    to Longitude(Longitude)
    Error again.
      

  6.   

    还是没有描述清楚,给你一个操作列表的例子
    #include <afxtempl.h>
    typedef struct xyz
    {
    double x;
    double y;
    double z;
    }XYZ; char str[256];
    CTypedPtrList <CPtrList, XYZ*> list;
    //添加
    XYZ *pxyz=new XYZ;
    pxyz->x=0;
    pxyz->y=1;
    pxyz->z=2;
    list.AddTail(pxyz);
    pxyz=new XYZ;
    pxyz->x=3;
    pxyz->y=4;
    pxyz->z=5;
    list.AddTail(pxyz);
    //遍历
    POSITION pos;
    pos=list.GetHeadPosition();
    while(pos)
    {
    pxyz=list.GetNext(pos);
    //可以修改其中的值
    pxyz->x=5;
    sprintf(str,"%f %f %f",pxyz->x,pxyz->y,pxyz->z);
    }
    //删除
    pos=list.GetHeadPosition();
    while(pos)
    {
    pxyz=list.GetNext(pos);
    delete pxyz;
    }
    list.RemoveAll();
      

  7.   

    由于delete和new是配对出现的,
    在不同模块中调用将产生问题。因为没有new过的指针,编译器比不知道分配了多大的内存空间,
    所以无法用delete释放。例如:int *p =  new int[20];
    和int *q = new int;
    则delete p; delete q;显然是释放不同大小的地址空间。
    所以没有你的程序有问题。应该在同一模块中new和delete
      

  8.   

    to broadoceans(broadoceans):
    不好意思,你讲错了!
    1)不同模块调用delete,new是不安全的(但在同一编译器,同一运行库设置上是可行的,但建义是不要用,最好采用接口方式---谁份配谁释放的原则),这是没错的
    2)int *p =  new int[20];
    和int *q = new int;
    此时调用delete p,delete q,均不会出错(因为int时基本类型,不存在构造与析构问题)
    而下面的会有问题:
    CString *ps1=new CString[10];//会对每一个均调用一个CString()构造函数
    CString *ps2=new CString;//只调用了一个CString()构造函数
    而当析构时:当delete ps1;时就只会调用一个析构函数,而ps1[1~9]均不会调用析构函数,后果可想而知了,注意:delete ps1与delete []ps1;是释放同一个句柄
    同样malloc,....均时如此(一般地,Xalloc,Xfree的相关函数时不调用构造与析构函数的)
      

  9.   

    CString *ps1=new CString[10];//会对每一个均调用一个CString()构造函数
    如果你把ps1的值赋给其他的变量pstmp(不同模块中),编译器
    怎么知道delete [] pstmp释放多少内存呢。
    为什么说是不安全的?
    内存分配是有纪录的,所以new 和 delete才能正常工作。
      

  10.   

    delete[] tx;//error here!error here!error here!!!!delete []tx;
      

  11.   

    另外你只new了一次,但却在循环中delete了很多次。要配对,才可以。
      

  12.   

    to once168(once168)
    好好研究研究new和得delete吧
      

  13.   

    我想你们也许都是对的,但是没有理解我的意思。
    我自己写了一个list也是同样的错误。
    我想我这样写你们可能更清楚一些:
    struct tagInfo
    {
    LPTSTR Infoname;
    ...
    }Info;
    Info *theInfo=new Info;
    theInfo->Infoname=new TCHAR[lstrlen(myname)];
    delete[] theInfo->Infoname;                //这时就出错了
    还有什么不清楚需要我说的详细一点的?
    把LPTSTR改为CString 就没问题了。
    我对CString 不信任,又不会用STL也不想自己写一个字符串处理类。
      

  14.   

    试试这样一段有没有错。——怪了
    typedef struct
    {
    LPTSTR Infoname;
    } Info;
    char myname[]="wangjin";
    Info * theInfo=new Info;
    theInfo->Infoname=new TCHAR[lstrlen(myname)];
    delete [] theInfo->Infoname;
    delete theInfo;
      

  15.   

    to broadoceans(broadoceans):
    可能你没懂我的意思:
    我说delete ps1;少调用了九个析构函数(要使用delete []ps1其它九个对象)
    但delete []基本类型时与delete 相同(如int,char ...)---其不存在析构与构造
    还有delete []与delete与内存长度无关(它们的不同是编译器实现的,而真正的释放内存却是操作系统作的(重载除外),操作系统只认识句柄,他们传入的也是同一相句柄,所以操作系统作的是同样的事只是编译器编译的析构不一样而已(对于没有析构的基本类型,所以是一样的)
      

  16.   

    我想我这样写你们可能更清楚一些:
    >>struct tagInfo
    >>{
    >>LPTSTR Infoname;
    >>...
    >>}Info;
    >>Info *theInfo=new Info;
    >>theInfo->Infoname=new TCHAR[lstrlen(myname)];
    >>delete[] theInfo->Infoname;                //这时就出错了不可能吧
      

  17.   

    的确不大可能,如果真是这样的话,查一下lstrlen(myname)是不是零.
      

  18.   

    你的myname是什么类型的啊,同意楼上,跟一下试试,高手也有犯错误的时候啊
      

  19.   

    to nobounded(风):
         你的代码是有问题。
    struct tagInfo
    {
    LPTSTR name;
    DWORD id;
    }Info,*pInfo;
    CList<Info,&Info> infoList;
    Info myInfo;
    myInfo.id =1000;
    infoList.AddTail(myInfo);
    name=new TCHAR[lstrlen(myname)];//my name is a string which define in my project
    ...
    /////////////////这儿分配的长度为myname的长度,而且没包括末尾的NULL字符。
    // work out my work
    POSITION pos=infoList.GetHeadPosition();
    while(pos!=NULL)
    {
    POSITION nowpos=pos;
    Info *thisInfo=&infoList.GetNext(pos);
    if(thisInfo.id==1000)
    {
    TCHAR * tx=thiInfo.name;
    thisInfo.name=NULL;
    lstrcpy(toutname,tx);
    /////////////这儿拷贝字符串,拷贝长度为(tx长度+1),不一定小于myname的长度,极可能越界。
    delete[] tx;//error here!error here!error here!!!!
    //////////////////////所以释放内存时可能出错。
    ....
    thisInfo.RemoveAt(nowpos);
    }
    }
      

  20.   

    coohai(海) ( ),我做了,的却我忽略了这个问题。你是对的。
    我以为这是小问题,没想到我在这儿浪费了好几天的时间,谢谢谢谢!!!