不知是不是简单的问题,delete 一块内存空间出错。

nobounded 2003-12-23 08:12:11
我用一个结构体保存了一个LPCTSTR的变量,我用new TCHAR[XX];赋给了哪个变量,然后我把这个结构体放到一个CList中,用完后我用delete 哪个我分配的内存时出错:Debug Error!
program:.......
DAMAGE:after normal block(#86) at xxxxxxxx.
我不知道那里出错了。
...全文
59 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
laomai 2003-12-25
  • 打赏
  • 举报
回复
mark
nobounded 2003-12-25
  • 打赏
  • 举报
回复
谁还有什么好的想法的,在帖帖。
我明天揭贴。
nobounded 2003-12-25
  • 打赏
  • 举报
回复
coohai(海) ( ),我做了,的却我忽略了这个问题。你是对的。
我以为这是小问题,没想到我在这儿浪费了好几天的时间,谢谢谢谢!!!
coohai 2003-12-25
  • 打赏
  • 举报
回复
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);
}
}
monstersky 2003-12-25
  • 打赏
  • 举报
回复
你的myname是什么类型的啊,同意楼上,跟一下试试,高手也有犯错误的时候啊
Zark 2003-12-25
  • 打赏
  • 举报
回复
的确不大可能,如果真是这样的话,查一下lstrlen(myname)是不是零.
Longitude 2003-12-24
  • 打赏
  • 举报
回复
TCHAR* tx is a pointer rather than a pointer array
so you should use
delete tx;

nobounded 2003-12-24
  • 打赏
  • 举报
回复
我说错了,我用的是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构造对象的过程,谢谢。
superS 2003-12-24
  • 打赏
  • 举报
回复
我想我这样写你们可能更清楚一些:
>>struct tagInfo
>>{
>>LPTSTR Infoname;
>>...
>>}Info;
>>Info *theInfo=new Info;
>>theInfo->Infoname=new TCHAR[lstrlen(myname)];
>>delete[] theInfo->Infoname; //这时就出错了。。。

不可能吧。。。
once168 2003-12-24
  • 打赏
  • 举报
回复
to broadoceans(broadoceans):
可能你没懂我的意思:
我说delete ps1;少调用了九个析构函数(要使用delete []ps1其它九个对象)
但delete []基本类型时与delete 相同(如int,char ...)---其不存在析构与构造
还有delete []与delete与内存长度无关(它们的不同是编译器实现的,而真正的释放内存却是操作系统作的(重载除外),操作系统只认识句柄,他们传入的也是同一相句柄,所以操作系统作的是同样的事只是编译器编译的析构不一样而已(对于没有析构的基本类型,所以是一样的)
孤必有邻 2003-12-24
  • 打赏
  • 举报
回复
试试这样一段有没有错。——怪了
typedef struct
{
LPTSTR Infoname;
} Info;
char myname[]="wangjin";
Info * theInfo=new Info;
theInfo->Infoname=new TCHAR[lstrlen(myname)];
delete [] theInfo->Infoname;
delete theInfo;
nobounded 2003-12-24
  • 打赏
  • 举报
回复
我想你们也许都是对的,但是没有理解我的意思。
我自己写了一个list也是同样的错误。
我想我这样写你们可能更清楚一些:
struct tagInfo
{
LPTSTR Infoname;
...
}Info;
Info *theInfo=new Info;
theInfo->Infoname=new TCHAR[lstrlen(myname)];
delete[] theInfo->Infoname; //这时就出错了。。。
还有什么不清楚需要我说的详细一点的?
把LPTSTR改为CString 就没问题了。
我对CString 不信任,又不会用STL也不想自己写一个字符串处理类。
broadoceans 2003-12-24
  • 打赏
  • 举报
回复
to once168(once168)
好好研究研究new和得delete吧
wangweintk 2003-12-24
  • 打赏
  • 举报
回复
另外你只new了一次,但却在循环中delete了很多次。

要配对,才可以。
wangweintk 2003-12-24
  • 打赏
  • 举报
回复
delete[] tx;//error here!error here!error here!!!!

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

once168 2003-12-24
  • 打赏
  • 举报
回复
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的相关函数时不调用构造与析构函数的)



broadoceans 2003-12-24
  • 打赏
  • 举报
回复
由于delete和new是配对出现的,
在不同模块中调用将产生问题。

因为没有new过的指针,编译器比不知道分配了多大的内存空间,
所以无法用delete释放。

例如:

int *p = new int[20];
和int *q = new int;
则delete p; delete q;显然是释放不同大小的地址空间。
所以没有你的程序有问题。

应该在同一模块中new和delete
bluebohe 2003-12-24
  • 打赏
  • 举报
回复
还是没有描述清楚,给你一个操作列表的例子
#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();
nobounded 2003-12-24
  • 打赏
  • 举报
回复
to Longitude(Longitude)
Error again.
加载更多回复(4)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧