Avoid wild pointer problems in cocos2d-x ccarray usage

Source: Internet
Author: User


Problems and phenomena

  

Previously, a runtime error occurred while debugging the cocos2d-x + cocostudio game program. From the call stack perspective, the error pointer stops ~ Ccnodergba ().


Analysis 1


Ccnodergba is a subclass inherited from ccnode. It mainly adds the attribute control function related to the node transparency.

  

class CC_DLL CCNodeRGBA : public CCNode, public CCRGBAProtocol


Ccnodergba is the direct parent class of ccsprite and Widget (that is, uiwidget. Therefore, the error object should be related to the ccsprite and Widget objects and possible subclass objects.

Analysis 2


The specific error stack content cannot be found. The hierarchy analysis from the stack is most likely the Hierarchy Process (level-1 structure, which is the structure rule of C ++, from child to parent to grandfather ...) the above error is generated at the end, and it can be roughly estimated that memory crashes.



Analysis 3


Since the problem is initially located in memory crash, it is likely related to pointer usage. Recall that some time ago (and a long time ago-in fact, this part of the code was available a long time ago), and the system was running normally-of course, before the newly added function was added.

So how can we analyze bugs as soon as possible? There are nearly 5000 lines of code! Fortunately, most of them have been running, so I started from the test instance (do not dare to use the zoom-out model: that is, scale down from the original 200 modules (mainly through the annotation shielding method) to the 100 modules to be tested ). Good! In the simplest operation test, the new function is normal! This gives me great encouragement!


As a result, I continued to use the test instance method and tested the new functions one by one (repeatedly ). Finally, the scope is gradually located in a rough implementation algorithm.


Problem Solving


The problem is: The C ++ wild pointer problem! The related code is as follows:

// Previously stated: card * cells [4] = {null}; cells [col] = (card *) tableaupiles [whichcolumnforcc]-> lastobject (); card * t2 = cells [col]; cells [col]-> setposition (m_pcurnode-> getchildbytag (10006 + col)-> getposition ()); m_pcurnode-> reorderchild (cells [col], ++ zindexforall); cells [col]-> setposition (m_pcurnode-> getchildbytag (10006 + col)-> getposition ()); m_pcurnode-> reorderchild (cells [col], ++ zindexforall); tableaupiles [whichcolumnforcc]-> removelastobject ();

The problem lies in the first and last sentences. The first sentence indicates pointing the cell [col] pointer to the location of a card object with memory allocation. In the last sentence, the corresponding memory of this object is released! As a result, cells [col] points to a zombie.


Botnets are terrible! We have all seen stories of similar genres! In my game, the cell [col] pointer genie can still move on the screen, as if it were a normal genie !!! This is also one of the reasons why I directly used the previous Code but have not found it yet (of course, the root cause is also closely related to my c ++ function ).


Further Analysis


We all know that the data type ccarray is very useful because it inherits from the existing structure in STL and improves the efficiency. In particular, it provides a lot of methods to simplify Array Operations. However, there are also deficiencies: when using ccarray, I will not repeat the retain issue-some on the network. In normal cocos2d-x encoding, the use of retain will call the corresponding release at the end; however, when you use the cocostudio UI editor or scenario editor for development, you do not need or cannot call release. For details, hanrea tells me that the UI parser automatically handles the release of the scenario content. Of course, I have not analyzed their source code, so I just come to this conclusion. Of course, the problems I have spent a lot of time to overcome have proved this point.


Next, the removelastobject method has a bool type parameter. The default value is true, which means the corresponding memory is released. The source code is as follows:

void CCArray::removeLastObject(bool bReleaseObj){    CCAssert(data->num, "no objects added");    ccArrayRemoveObjectAtIndex(data, data->num-1, bReleaseObj);}

Follow up:

void ccArrayRemoveObjectAtIndex(ccArray *arr, unsigned int index, bool bReleaseObj/* = true*/){    CCAssert(arr && arr->num > 0 && index < arr->num, "Invalid index. Out of bounds");    if (bReleaseObj)    {        CC_SAFE_RELEASE(arr->arr[index]);    }        arr->num--;        unsigned int remaining = arr->num - index;    if(remaining>0)    {        memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1], remaining * sizeof(CCObject*));    }}

Note that when the first if statement is true, the corresponding memory is actually released. Please refer to the game code above.


Finally, it is easy to correct the error. Modify the last sentence as follows:

TableauPiles[whichColumnForCC]->removeLastObject(false);


Obviously, passing the parameter "false" means that only the subscript adjustment (arr-> num is reduced by 1) in this array, and the memory corresponding to the last node is not released. Instead, the memory corresponding to the last array node is received by the cell [col] pointer. As a result, we have avoided a wild pointer (botnet) event. Everything is OK naturally!



This article from the "Qingfeng" blog, please be sure to keep this source http://zhuxianzhong.blog.51cto.com/157061/1550989

Avoid wild pointer problems in cocos2d-x ccarray usage

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.