删除导致有效的struct指针中断

时间:2013-10-23 23:00:45

标签: c++ heap delete-operator

我正在摸着这个。如果只有我能看到它或其中一个不起眼的陷阱,这是其中一个具有真正简单答案的问题。问题是我在一个函数中新建一个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) );

等。

有效。它可能不像其他一些方法那样优雅,但它暂时起作用或似乎并且它在主代码体中清楚地记录下来,发生了什么,所以它有它的好处。

2 个答案:

答案 0 :(得分:4)

delete[] pTt;导致未定义的行为,因为您使用new而不是new[]进行了分配。使用delete

如果你已经尝试过,很可能你没有遵守三条规则(google it)。 memcpy( &Tt, pTt, sizeof( *pTt ) );可能会分散本地TtpTt中某些资源的所有权。当Tt超出范围时,将调用其析构函数。当你调用delete时,pTt的析构函数。如果析构函数试图释放相同的资源,那么你将会崩溃。

在这种情况下请勿使用memcpy。使用复制构造函数。

TICKTYPE Tt = *pTt;

答案 1 :(得分:2)

当指针指向单个元素

时,您正在使用数组 - delete