我正在为这个挠头。这要么是那些只有我能看到它才有真正简单答案的问题之一,要么是一个晦涩难懂的问题之一。问题是我在一个函数中新建了一个结构对象,将指针保存到一个出队,在另一个函数中检索该指针,然后一旦使用了结构的数据,就试图删除堆上的对象。一切都发生在一个类实例中。这样做时,我得到了炸弹。我不太明白为什么。它是创建时和检索后的有效指针。我可以写/读它。但是当试图删除它时,我得到了炸弹。
//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部分
谢谢大家的建议。
删除 [] 与删除
我很绝望,所以我也尝试了 delete[] ,这恰好是我复制的那个。我已经尝试在两个地方删除并仍然得到该行为。
“显示 TICKTYPE”
我会展示 TICKTYPE,但现在我看它已经从相当简单到相当复杂,其中至少引用了 2 个其他结构。我必须发布(和格式化)几页代码。根据下面的评论,我将尝试将其视为崩溃的根源。谢谢你。
“在删除之前检查 pTt ia 是否有效。”
我已经尝试在删除之前对其进行读写,一切似乎都很好。此外,Vis Stud 在删除之前在结构中显示有效数据。在我进一步研究时,我会记住这一点。
“三法则”
啊,很可能是这样。
我还没有解决方案,但是当我这样做时,我会回复。你们都提供了一些好主意,我不再摸不着头脑了。只是埋头工作。敬请关注...
再次感谢。(PS 'da bomb' 通常是个好东西,但英语的美妙之处在于你可以编造单词并且仍然能够理解重点'一个更精确但无聊的术语应该是 GPF、ASSERT 等。我在交易时需要这些东西有时用 C++ ...... :) 没有人在这里谈论过编码的心理......哈哈。”)
第三部分
事实证明,问题出在 memcpy 上。如果我取出所有 memcpy 的对象将被删除。然而,这给我留下了复制的问题。我需要从参考 TICKTYPE& tp 转到指针 TICKTYPE* pTt(请参阅 QueueEvent)。
我尝试按照下面的酷建议创建一个 Copy 构造函数。如果使用了传统的 copy-ctor,例如
TICKTYPE( TICKTYPE const& ref )
{
a = ref.a;
b= ref.b;
c = ref.c;
d= ref.d;
e = ref.e; //etc...
}
主结构中有几个结构被深度复制,还有一些 MSFT 结构 FILETIME 和 SYSTEMTIME 我不知道它们是否已经有复制ctor。
然后是从 ref 到 ptr 的问题。我尝试了一个带有签名的复制 ctor
TICKTYPE* 参考;
然后
pTt = rTt
其中 pTt 是 TICKTYPE*,rTt 是 TICKTYPE rTt。那没有编译。
问题
将包含其他结构的结构从 ref 复制到新指针 var(从堆栈到堆)的最佳方法是什么。我想将该数据从堆栈移动到堆中以进行更永久的存储。
我正在考虑对每个结构级别进行 mem 副本,这样 memcpy 复制的任何结构都不会嵌入 struts。你怎么看?好方法?
第 4 部分
再次感谢所有回复的人。你的建议帮助很大。该问题是在对顶层结构进行 memcpy 时产生的。在主顶层结构内对从属结构进行 memcpy,只要它们又没有从属结构,就不会导致删除失败。我在从属结构上使用了 memcpy,在顶级结构上使用了变量复制。它看起来像这样
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) );
等等
这样可行。它可能不像其他一些方法那样优雅,但它暂时有效或似乎有效,并且它都清楚地记录在主要代码体中,发生了什么,所以它有它的好处。