delete 出错?莫名其妙,大家来

时间:2022-09-20 10:38:43

CFTSender* sender = NULL;
sender = new CFTSender(m_sockUDP);
delete sender;                // error: This may be due to a corruption of the heap...

/* construction/destruction */
CFTSender::CFTSender(SOCKET sock)
{
m_sock = sock;
int nlen = sizeof(int);
getsockopt(m_sock, SOL_SOCKET, SO_TYPE, (char*)&m_nSockType, &nlen); // save socket type
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

m_hThrdProc = NULL;
m_nRepeatTimes = FT_REPEAT_TIMES;
m_bQuit = false;

InitializeCriticalSection(&m_CS);
}
CFTSender::~CFTSender()
{
DeleteCriticalSection(&m_CS);
}

27 个解决方案

#1


该回复于2010-12-03 14:00:11被版主删除

#2


该回复于2010-11-19 13:49:17被版主删除

#3



sender = new CFTSender(m_sockUDP);
delete sender;                // error: This may be due to a corruption of the heap..

真的是莫名其妙,帮顶帮顶

#4


你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

#5


引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~

#6


引用 5 楼 zhaoxueqian1988 的回复:
引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~


那你就要查看一下你前后的代码咯,看看哪里破坏堆栈了
关键是看一些内存的分配,回收,赋值之类的。看看有没有越界等等

#7


引用 5 楼 zhaoxueqian1988 的回复:
引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~


你是说这样也会出错?

CFTSender::CFTSender(SOCKET sock)
{
}
CFTSender::~CFTSender()
{
    //DeleteCriticalSection(&m_CS);
}
不相信啊.

这里判断下
if(sender != NULL)
delete sender; 

#8


判断下再delete就没问题了

#9


delete 提示堆错误肯定是访问越界了,因为new分配的内存有一个0xFDFDFDFD标记,一个标记被破坏,delete就会提示那个错误了.
你看看内存中,
getsockopt(m_sock, SOL_SOCKET, SO_TYPE, (char*)&m_nSockType, &nlen); // save socket 
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));
这些操作,或者你程序中其它操作,有没有破坏这个标记.

#10


m_CS 不会是全局变量吧

#11


修改一下构造函数,不要参数,试试

#12


申请空间了也先判断下吧~

#13


该回复于2010-11-19 13:51:09被版主删除

#14


呵呵,调试一下把,代码有问题的哦,getsockopt(m_sock, SOL_SOCKET, SO_TYPE, (char*)&m_nSockType, &nlen); // save socket  
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));有问题

#15


可能是其它地方指针越界了

#16


delete出错,一般是内存分配越界引起的。

#17


原因找到:
此析构函数是虚析构。
调试运行的时候发现一个类中的变量__vfpt指针。每次构造完成这个指针的值无效。

把析构函数的虚属性去掉后,该指针消失,运行正常。

#18


为不包含virtual函数的类 设计irtual析构函数是一个馊主意
                                           ----scott meyers

#19



那你就要查看一下你前后的代码咯,看看哪里破坏堆栈了
关键是看一些内存的分配,回收,赋值之类的。看看有没有越界等等

#20


__vfpt其实就是一个针对包含virtual函数的一个函数指针表的指针,这个指针指向函数表中的一个值,在一个类的继承体系中调用对应的函数
   如基类包含virtual getdata函数,子类也包含,而你将子类的对象赋值给基类的指针,你通过这个指针调用getdata函数时,会同过vfpt指针在vtbl中对应的函数,即子类的getdata函数。

#21


如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
    你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中才定义virtual析构函数

#22


引用 21 楼 vc_zsy 的回复:
如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
  你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中……


支持..

#23


解决就好。看到标题就猜测是delete之前某个方法中的问题。

#24


来晚了, 那捧场吧。

#25


引用 21 楼 vc_zsy 的回复:
如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
  你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中……

很透彻,谢谢。

但是如果用VC编辑器的向导自动生成类的话,它会默认将析构设置为虚的,看来这是画蛇添足了。

#26


该回复于2010-11-22 15:37:33被版主删除

#27


结贴!!!

#1


该回复于2010-12-03 14:00:11被版主删除

#2


该回复于2010-11-19 13:49:17被版主删除

#3



sender = new CFTSender(m_sockUDP);
delete sender;                // error: This may be due to a corruption of the heap..

真的是莫名其妙,帮顶帮顶

#4


你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

#5


引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~

#6


引用 5 楼 zhaoxueqian1988 的回复:
引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~


那你就要查看一下你前后的代码咯,看看哪里破坏堆栈了
关键是看一些内存的分配,回收,赋值之类的。看看有没有越界等等

#7


引用 5 楼 zhaoxueqian1988 的回复:
引用 4 楼 allen_zhang 的回复:
你的m_addrRecver这个是什么类型?

要错的话,很有可能是
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));

这里越界了导致,其他的看不出问题

我试过直接把构造里的东西全部注释,结果一样,哎~


你是说这样也会出错?

CFTSender::CFTSender(SOCKET sock)
{
}
CFTSender::~CFTSender()
{
    //DeleteCriticalSection(&m_CS);
}
不相信啊.

这里判断下
if(sender != NULL)
delete sender; 

#8


判断下再delete就没问题了

#9


delete 提示堆错误肯定是访问越界了,因为new分配的内存有一个0xFDFDFDFD标记,一个标记被破坏,delete就会提示那个错误了.
你看看内存中,
getsockopt(m_sock, SOL_SOCKET, SO_TYPE, (char*)&m_nSockType, &nlen); // save socket 
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));
这些操作,或者你程序中其它操作,有没有破坏这个标记.

#10


m_CS 不会是全局变量吧

#11


修改一下构造函数,不要参数,试试

#12


申请空间了也先判断下吧~

#13


该回复于2010-11-19 13:51:09被版主删除

#14


呵呵,调试一下把,代码有问题的哦,getsockopt(m_sock, SOL_SOCKET, SO_TYPE, (char*)&m_nSockType, &nlen); // save socket  
memset(&m_addrRecver, 0, sizeof(SOCKADDR_IN));有问题

#15


可能是其它地方指针越界了

#16


delete出错,一般是内存分配越界引起的。

#17


原因找到:
此析构函数是虚析构。
调试运行的时候发现一个类中的变量__vfpt指针。每次构造完成这个指针的值无效。

把析构函数的虚属性去掉后,该指针消失,运行正常。

#18


为不包含virtual函数的类 设计irtual析构函数是一个馊主意
                                           ----scott meyers

#19



那你就要查看一下你前后的代码咯,看看哪里破坏堆栈了
关键是看一些内存的分配,回收,赋值之类的。看看有没有越界等等

#20


__vfpt其实就是一个针对包含virtual函数的一个函数指针表的指针,这个指针指向函数表中的一个值,在一个类的继承体系中调用对应的函数
   如基类包含virtual getdata函数,子类也包含,而你将子类的对象赋值给基类的指针,你通过这个指针调用getdata函数时,会同过vfpt指针在vtbl中对应的函数,即子类的getdata函数。

#21


如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
    你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中才定义virtual析构函数

#22


引用 21 楼 vc_zsy 的回复:
如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
  你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中……


支持..

#23


解决就好。看到标题就猜测是delete之前某个方法中的问题。

#24


来晚了, 那捧场吧。

#25


引用 21 楼 vc_zsy 的回复:
如果这个类不包含其他的virtual函数,请将析构函数的virtual性去掉。
原因:
  你调用构造函数时,会根据virtual函数表生成对应的vtbl表及动态的vfpt指针,这个时候你不存在virtual函数,则不会生成这两个值,而析构函数中调用了virtual析构函数,则需要根据vtbl表及动态的vfpt指针来调用对应的析构函数,必然出错。

请在最少包含一个virtual函数的类中……

很透彻,谢谢。

但是如果用VC编辑器的向导自动生成类的话,它会默认将析构设置为虚的,看来这是画蛇添足了。

#26


该回复于2010-11-22 15:37:33被版主删除

#27


结贴!!!