我正在摸着这个。如果只有我能看到它或其中一个不起眼的陷阱,这是其中一个具有真正简单答案的问题。问题是我在一个函数中新建一个struct对象,将指针保存到一个dequeue,在另一个func中检索该指针,然后一旦使用了struct的数据,就试图删除堆上的对象。一切都发生在一个类实例中。这样做时,我得到 da bomb 。我无法弄清楚原因。它是创建时和检索后的有效指针。我可以写/读它。但是当我试图删除它时,我得到 da bomb 。
//This creates and saves the heap object
void CFoo::QueueEvent( TICKTYPE& tp )
{
TICKTYPE* pTt = new TICKTYPE;
memcpy( pTt, &tp, sizeof(tp) );
m_queuedevents.push_front( pTt );
}
//This retrieves it
int CFoo::ReplayQueuedEvents()
{
long lSz = m_queuedevents.size();
for( int i = 0; i < lSz; i++ )
{
TICKTYPE Tt;
TICKTYPE* pTt = m_queuedevents.back();
//m_queuedevents.pop_back(); //bombs w or w/o this
//bombs w ot w/o memcpy
memcpy( &Tt, pTt, sizeof( *pTt ) );
//int iRtn = SendEvent( Tt );
ASSERT( SendEvent( Tt ) != ERR_FAILURE );
//This asserts before or after the memcpy.
delete[] pTt;
//delete pTt;
}
}
第2部分
谢谢大家的建议。
删除[] vs删除
我很绝望,所以我也尝试删除[],这恰好是我复制的那个。我在两个地方试过删除但仍然得到了行为。
“显示TICKTYPE”
我会展示TICKTYPE,但现在我看着它从相当简单到相当复杂,从而引用了至少2个其他结构。我必须发布(并格式化)几页代码。根据下面的评论,我会尝试将其视为崩溃的来源。谢谢。
“在删除之前检查pTt是否有效。”
我在删除之前尝试过读取和写入,似乎一切正常。此外,Vis Stud在删除之前显示结构中的有效数据。当我进一步研究这个时,我会记住这一点。
“三法则”
啊,很可能就是这样。我还没有解决方案,但是当我这样做时,我会回复。你们都提供了一些好主意,我不再挠头了。只是膝盖深入工作。请继续关注...
再次感谢。 (PS'da bomb'通常是一件好事,但英语的美妙之处在于你可以说出来并且仍然能够理解这一点'一个更精确但更无聊的术语可能是GPF,ASSERT等。我在交易时需要这些东西有时用C ++ ...... :)没有人在这里谈论编码的心理学。大声笑。“)
第3部分
事实证明问题在于memcpy。如果我取出所有memcpy的对象删除。然而,这让我有了复制的问题。我需要从参考TICKTYPE&amp; tp到指针TICKTYPE * pTt(参见QueueEvent)。
我尝试根据下面的酷建议创建一个Copy构造函数。如果使用传统的复制器,例如
,则会返回该问题TICKTYPE( TICKTYPE const& ref )
{
a = ref.a;
b= ref.b;
c = ref.c;
d= ref.d;
e = ref.e; //etc...
}
主结构中有一些结构被深层复制,并且有一些MSFT结构FILETIME和SYSTEMTIME,我不知道它们是否已经有复制ctors。
然后是从ref到ptr的问题。我尝试了一个带签名的复制文件
TICKTYPE * ref;
然后
pTt = rTt
其中pTt为TICKTYPE *且rTt为TICKTYPE rTt。那不编译。
问题
将包含其他结构的结构从ref复制到新指针var(从堆栈到堆)的最佳方法是什么。我想将数据从堆栈移到堆中以获得更长久的存储空间。
我正在考虑做每个结构级别的mem副本,这样memcpy复制的结构就不会有嵌入式struts。你怎么看?好方法?
第4部分
再次感谢所有回复的人。你的建议帮助很大。在执行顶级结构的memcpy时创建了该问题。在主要的顶层结构中执行从属结构的memcpy,只要它们反过来没有从属结构,就不会导致删除失败。我在subordinate结构上使用了memcpy,在顶级结构上使用了变量copy的变量。它看起来像这样
TYPE1 foo1;
foo1.a = foo.a
foo1.b = foo.b
foo1.c = foo.c
memcpy( foo1.d, foo.d, sizeof( foo.d) );
memcpy( foo1.e, foo.e, sizeof( foo.e) );
等。
有效。它可能不像其他一些方法那样优雅,但它暂时起作用或似乎并且它在主代码体中清楚地记录下来,发生了什么,所以它有它的好处。
答案 0 :(得分:4)
delete[] pTt;
导致未定义的行为,因为您使用new
而不是new[]
进行了分配。使用delete
。
如果你已经尝试过,很可能你没有遵守三条规则(google it)。 memcpy( &Tt, pTt, sizeof( *pTt ) );
可能会分散本地Tt
和pTt
中某些资源的所有权。当Tt
超出范围时,将调用其析构函数。当你调用delete时,pTt
的析构函数。如果析构函数试图释放相同的资源,那么你将会崩溃。
在这种情况下请勿使用memcpy
。使用复制构造函数。
TICKTYPE Tt = *pTt;
答案 1 :(得分:2)
当指针指向单个元素
时,您正在使用数组 -delete