Access violation reading location

I am new to cocos2dx. I am trying to convert my game from cocos2d to cocos2dx.
I start from this project (http://www.raywenderlich.com/32045/how-to-use-animations-and-sprite-sheets-in-cocos2d-2-x)
I got Access violation reading location.
I run the debug mode. The error is this line *bear~~>runAction;
I have no idea about this because it works perfectly when this line is written on init.
I paste my code here.

on header file, i have declared these pointers.
cocos2d::CCAction ***walkAction;
cocos2d::CCAction *moveAction;
cocos2d::CCSprite
**bear;
cpp file:
<pre>
bool HelloWorld::init {
if) {
return false;
}
CCMenuItemImage *pCloseItem = CCMenuItemImage::create);
// Place the menu item bottom-right conner.
pCloseItem~~>setPosition~~>getWinSize.width~~ 20, 20));
// Create a menu with the “close” menu item, it’s an auto release object.
CCMenu* pMenu = CCMenu::create;
pMenu~~>setPosition;
// Add the menu to HelloWorld layer as a child layer.
this~~>addChild;
// From Anim Bear cocos2d-iphone
*moveAction = NULL;
*walkAction = NULL;
this~~>setTouchEnabled;
*bearMoving = false;
CCSize winSize = CCDirector::sharedDirector~~>getWinSize ;
CCSpriteFrameCache cache = CCSpriteFrameCache::sharedSpriteFrameCache;
cache->addSpriteFramesWithFile;
cocos2d::CCSpriteBatchNode
spriteSheet = CCSpriteBatchNode::batchNodeWithFile;
this~~>addChild;
CCArray walkAnimFrames = new CCArray;
for {
char temp[30];
sprintf;
CCSpriteFrame
frame = cache~~>spriteFrameByName;
walkAnimFrames->addObject;
}
CCAnimation *walkAnim = CCAnimation::animationWithSpriteFrames;
*walkAction = CCRepeatForever::actionWithAction(CCAnimate::actionWithAnimation(walkAnim));

*bear = CCSprite::spriteWithSpriteFrameName;
*bear~~>setPosition);
//_bear~~>runAction(*walkAction);
spriteSheet~~>addChild;
return true;
}

// cpp with cocos2d-x
void HelloWorld::ccTouchesEnded
{
// Choose one of the touches to work with
CCTouch* touch = );
CCPoint location = touch~~>locationInView;
location = CCDirector::sharedDirector~~>convertToGL;
// Set up initial location of projectile
CCSize winSize = CCDirector::sharedDirector~~>getWinSize;
float bearVelocity = winSize.width / 3.0;
CCPoint moveDifference = ccpSub);
float distanceToMove = ccpLength;
float moveDuration = distanceToMove / bearVelocity;
if {
*bear->setFlipX;
}
else {
*bear~~>setFlipX;
}
*bear->stopAction;
if {
*bear~~>runAction;
}
*moveAction = cocos2d::CCSequence::create(
cocos2d::CCMoveTo::actionWithDuration(moveDuration, location),
cocos2d::CCCallFuncN::create(this, callfuncN_selector(HelloWorld::bearMoveEnded)),
NULL);

*bear~~>runAction;
*bearMoving = true;
}
void HelloWorld::bearMoveEnded
{
*bear~~>stopAction;
*bearMoving = false;
}

Your bear variable will be released by the autorelease pool during the next frame. This is why you get an access violation in ccTouchesEnded when accessing the variable.

Here is some more background on how the memory sstem works:
All objects you create with the static createXYZ functions will create autorelease objects.
This means these objects will be stored in the autorelease pool and have a retain count of one when the function returns.
After the current frame is completed, cocos2dx will go through the autorelease pool and will call release on all objects inside the pool.
If the retaincount drops to 0 because of this release call, the object is destroyed (this is the case for your bear_ variable)
After that, all objects are removed from the autorelease pool, so they do not get released multiple times.

To fix your issue, you must claim ownership on the object. That means your code must call retain() on the bear_ variable. A good place is right after the create call returns.
This will make sure that your object is not deleted by the autorelease pool.
Of course you are responsible to call release on any object you have retained yourself. Otherwise you get a memory leak.

As a general rule of thumb I code this way:
* Every member variable of the class MUST be retained. This makes sure your class actually has ownership on the members it stores.
* When a member variable is no longer needed by the class it MUST be release and MUST be set to NULL. This makes sure we have either a valid pointer or NULL stored in our members.
* The above point also applies if we store a new value to the variable.
* All member variables MUST be released in the objects destructor. This is to avoid memory leaks.

There is one exception to this rule: Circular dependencies. If object A hold a member of object B and object B holds a member of object A. One of them must be a “weak reference” i.e. it must not be retained. I normally put a comment in the code in that case. You should select the weak reference on how lifetimes of the objects are coupled. So if for example the lifetime of B is coupled to the lifetime of A, B should get a weak reference on A and A should get a strong reference to B.

1 Like

Thank you. Excellent answer.:slight_smile: