Vector<Node*> provided by Node::getChildren() contains invalid pointer.

Hi every body,
I met a problem as described in the subject.

As a context, I’m developing tower defense app with cocos2d-x 3.0 RC with Xcode 5.
The Scene with this problem handles nodes in one child layer.
The number of nodes are more than 10, but it’s rarely to go over 100.

When I met the issue, my code was like this;

void Battle::addTroop(int troopId)
{
    Troop* troop = Troop::create(troopId);
    troop->setTag(Battle::tagTroops);
    troop->retain();
    
    ....
    
    this->addingNodes.push_back(troop);
}

void Battle::update(float dt)
{
    Layer* field = static_cast<Layer*>(this->getChildByTag(Battle::tagField));
    
    for (std::vector<Node*>::iterator pos = this->addingNodes.begin(); pos != this->addingNodes.end(); ++pos) {
        field->addChild(*pos, Z_ORDER_OBJECT);
    }
    this->addingNodes.clear();
    
    ....
    
    for (Value node : field->getChildren()) {
        int tag = node->getTag();
        if (tag == Battle::tagTroops) {
            ....
        }
    }
    
    ....
    
    for (std::vector<Node*>::iterator pos = this->removingNodes.begin(); pos != this->removingNodes.end(); ++pos) {
        (*pos)->removeFromParent();
    }
    this->removingNodes.clear();
}

Every nodes are added or removed only in “update” method, and it works well for first few minutes playing.
but after that, eventually EXC_BAD_ACCESS error occurs on node->getTag() line.
Xcode can show the detail of variable when it crashes, so I checked that and got two patterns of information as follows;

  1. variable seems to be empty
    all the properties of cocos2d::Node* are not assigned or NULL.

  2. every value of property didn’t make a sense
    they contain very huge int value or something like that.

I guess that it is like pointers were already deallocated or overwritten with completely different thing, I’m not familiar with c++ though.

Finally, as an alternative solution, I changed my code like below;

void Battle::addTroop(int troopId)
{
    Troop* troop = Troop::create(troopId);
    
    Battle::tagTroops++;
    if (Battle::tagTroops > Battle::tagTroopsTo)
        Battle::tagTroops = Battle::tagTroopsFrom;
    
    troop->setTag(Battle::tagTroops);
    troop->retain();
    
    ....
    
    this->addingNodes.push_back(troop);
}

void Battle::update(float dt)
{
    Layer* field = static_cast<Layer*>(this->getChildByTag(Battle::tagField));
    
    for (std::vector<Node*>::iterator pos = this->addingNodes.begin(); pos != this->addingNodes.end(); ++pos) {
        field->addChild(*pos, Z_ORDER_OBJECT);
        this->existingNodeTags.push_back((*pos)->getTag());
    }
    this->addingNodes.clear();
    
    ....
    
    for (std::vector<int>::iterator pos = this->existingNodeTags.begin(); pos != this->existingNodeTags.end(); ++pos) {
        Node* node = field->getChildByTag(*pos);
        if (node == nullptr) continue;
        
        if (tag >= Battle::tagTroopsFrom && tag <= Battle::tagTroopsTo) {
            ....
        }
    }
    
    ....
    
    for (std::vector<Node*>::iterator pos = this->removingNodes.begin(); pos != this->removingNodes.end(); ++pos) {
        for (std::vector<int>::iterator tag = this->existingNodeTags.begin(); tag != this->existingNodeTags.end();) {
            if ((*pos)->getTag() == *tag) {
                tag = this->existingNodeTags.erase(tag);
            }
            else {
                ++tag;
            }
        }
        (*pos)->removeFromParent();
    }
    this->removingNodes.clear();
}

In this style, it works pretty well with no exception, (tags became little bit messy though)
What I’d like to understand is the reason why an EXC_BAD_ACCESS appeared on my first code.

If there is someone who has any idea for this situation,
I’m happy with any advice or improvement suggestion.
Also I’m afraid that it may not be an cocos2d-x problem.

Thank you.

do-low