Assertion when deleting CCSprite

Hi all

Platform

Windows 7 64 bit
Visual Studio Ultimate 2012
Microsoft Visual C runtime 11.0

Problem

I’ve encountered a strange error when removing a child CCSprite. The program crashes with an assertion from MSVCR every time. My Sprite class is as following:

#include "BrickNode.h"

USING_NS_CC;

BrickNode* BrickNode::createWithType(int type)
{
    CCTexture2D *tex = CCTextureCache::sharedTextureCache()->textureForKey("gems.png");
    CCSpriteFrame *frame = CCSpriteFrame::createWithTexture(tex, CCRectMake(type*64.000f,0,64.000f,64.000f),false,CCPointMake(0,0),CCSizeMake(64.000f,64.000f));
    return  (BrickNode*) BrickNode::createWithSpriteFrame(frame);
}

void BrickNode::setBrickType(int t)
{
    this->bricktype = t;
}

The stack trace is below:

@ msvcr110d.dll!CrtIsValidHeapPointer Line 2036 C+
msvcr110d.dll!free_dbg_nolock Line 1322 C++
msvcr110d.dll!free_dbg Line 1265 C+
msvcr110d.dll!operator delete Line 54 C
+
HelloCpp.exe!cocos2d::CCSprite::`vector deleting destructor’ C*+
HelloCpp.exe!cocos2d::CCObject::release Line 86 C*+
HelloCpp.exe!cocos2d::ccArrayRemoveObjectAtIndex Line 199 C*+
HelloCpp.exe!cocos2d::ccArrayRemoveObject Line 237 C*+
HelloCpp.exe!cocos2d::CCArray::removeObject Line 295 C*+
HelloCpp.exe!cocos2d::CCNode::detachChild Line 741 C*+
HelloCpp.exe!cocos2d::CCNode::removeChild Line 657 C*+
HelloCpp.exe!cocos2d::CCNode::removeChild Line 638 C++
@
Here is the source for*CrtIsValidHeapPointer taken from the MSVCR library:

/***
*int _CrtIsValidHeapPointer() - verify pointer is from 'local' heap
*
*Purpose:
*       Verify pointer is not only a valid pointer but also that it is from
*       the 'local' heap. Pointers from another copy of the C runtime (even in the
*       same process) will be caught.
*
*Entry:
*       const void * pUserData     - pointer of interest
*
*Return:
*       TRUE - if valid and from local heap
*       FALSE otherwise
*
*******************************************************************************/
extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
        const void * pUserData
        )
{
        if (!pUserData)
            return FALSE;

        if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
            return FALSE;

        return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}

The error does only occure on Windows. I’ve tried compiling and running on iOS, and there is no probleme there. Could this be an implementation specific bug in Cocos2d-x on Windows or with this specific version of MSVCR (11.0)? Or is it because of the memory management in cocos2d-x that MSVCR is just suspisious about?

Note i tried both statically and dynamically linking cocos2d-x, and both with MSVCR in release and debug mode.

Any clues?

Solved it while trying to dig out more info for this post haha :slight_smile:

Well, hint to anybody getting this error:

It’s was only when i add the “type” variable to my extended CCSprite class BrickNode that it crashed. The following console output also appeared:

HEAP[HelloCpp.exe]: Heap block at 05D52800 modified at 05D529E0 past requested size of 1d8

I figured it was because something allocated less memory than required somewhere, and because it only occured when i added a new variable to BrickNode i figured it was a problem there.

The ‘new’ called in CCSprite did of course only allocate enough for a standard CCSprite, and i needed more than that for my BrickNode. I changed the constructor to the following, and everything worked flawless:

BrickNode* BrickNode::createWithType(int type)
{
    CCTexture2D *tex = CCTextureCache::sharedTextureCache()->textureForKey("gems.png");
    CCSpriteFrame *frame = CCSpriteFrame::createWithTexture(tex, CCRectMake(type*64.000f,0,64.000f,64.000f),false,CCPointMake(0,0),CCSizeMake(64.000f,64.000f));

    BrickNode *pobSprite = new BrickNode();
    if (frame && pobSprite && pobSprite->initWithSpriteFrame(frame))
    {
        pobSprite->autorelease();
        return pobSprite;
    }

    CC_SAFE_DELETE(pobSprite);
    return NULL;
}
1 Like

Thankyou very much !
This solved my very critical problem !

Thanks, I had a similar problem with subclassing ui::Button. The solution for me was to copy and paste whichever function I was calling, say Button::create(), and just replacing all instances of the string “Button” with “MyButtonClass”.