Skip to main content
gamedev.net
🔒 Locked

Problem with STL vector

Started by Mage2k Mar 20, 2003 at 3:37 AM 8 replies 600+ views
Original Post
Mage2k
Mage2k
Ok. I posted this question here a couple of months ago but the only answer I received was "Use STLport instead of the vc++ libs", which I did to no avail. So, here is a more detailed explanation of what is happening in hopes of someone having a real solution. Basically, what is happening is that when I use vectors in my code I can only ever put one object in each vector. When debugging in VC++, the variables window lists info for three members of each vector: _M_start, _M_finish, and _M_end_of_storage. After placing one object in a vector _M_start correctly lists the info for the object placed in the vector, but the info for _M_finish is listed as "CXX0030: Error: Expression cannot be evaluated" and subsequent additions of objects to the vector are not successfull -- _M_finish is still listed as "CXX0030: Error: Expression cannot be evaluated." Here is the pertinent code:
    
class SceneGraph
{
public:
	void addNode(Node* _parent, Node* _child);
		
private:
	std::vector<Node*> msceneNodes;
	RootNode* mrootNode;
};

/*the constructor builds mrootNode and adds it to the msceneNodes vector (the first node)*/
SceneGraph::SceneGraph()
{
	mrootNode = new RootNode();
	msceneNodes.push_back(mrootNode);
}

void SceneGraph::addNode(Node* _parent, Node* _child)
{
        if(_parent == NULL)
	{
		_child->setParent(mrootNode);
		msceneNodes.push_back(_child);
		mrootNode->attachChild(_child);
		
	}
	else
	{
		//make sure _parent is in the graph

		std::vector<Node*>::iterator it = msceneNodes.begin();
		bool found = FALSE;
		for(; it != msceneNodes.end(); ++it)
		{
			if((Node*) it == _parent)
			{
				found = TRUE;
				break;
			}
		}
		
		if(found)
		{
			_child->setParent(_parent);
			_parent->attachChild(_child);
			msceneNodes.push_back(_child);
		}
	}
	return;
}
    
If I am adding the node to the root node I pass NULL for the parent and otherwise search thru the msceneNodes to make sure that the parent passed is already in the graph. I realize that I don't have anything in the above code for what happens if the parent is not in the graph, but for this problem that is irrelevent. So, what is happening is that the second and all subsequent calls to pushback() on any vector fail so that I can get at most one child per node in the graph. This is REALLY frustrating me as this is basic scene graph/node and vector stuff. Also, of note: I have reproduced the same problem with somebody else's scene graph code, so I'm pretty sure that the problem is not actually with my code. As far as the compiler goes I have added C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VC98\INCLUDE\STLPORT to my list of include directories as per STLport docs. Is there anything else I need to do, or is it something else? [edited by - Mage2k on March 20, 2003 4:40:18 AM]
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
Qw3r7yU10p!
Qw3r7yU10p!
The iterator is not necessarily a pointer to the object. You're casting it (in a very unsafe C-style cast) to a (Node*).

To use an interator correctly you need to dereference it

(*it)

this will now be whatever type is stored in the container.

edit: a few links
sgi's stl documentation
the iterator docs
what a trivial iterator implementation must be able to do

[edited by - petewood on March 20, 2003 4:49:37 AM]
Mage2k
Mage2k
Ok, but that still doesn''t fix the problem I posted about. The problem occurs when calling pushback() on a vector such as in the line:

msceneNodes.push_back(_child);

which doesn''t involve the use of iterators at all...

Any other ideas?
Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
Qw3r7yU10p!
Qw3r7yU10p!
do you mean you tried it and it didn't fix it?

quote:
So, what is happening is that the second and all subsequent calls to pushback() on any vector fail


In what way does it fail?

edit: please be detailed. I'm beginning to think that you are looking at _M_finish to determine whether the push_back has succeeded. Why do you think that will change? It shouldn't concern you. Does msceneNodes.size() really not change?

[edited by - petewood on March 20, 2003 5:20:01 AM]
Advanced Bug
Advanced Bug
The problem migth occur because the "if((Node*) it == _parent)" test fails (I can''t even get it compiled with my compiler). Try to replace it with "if(*it == _parent)".
Mage2k
Mage2k
Problem solved! Well, the problem is still there, but now I know that I have been barking up the wrong tree the whole time. Vectors are working fine, all objects added are added. Pete, thanx for the suggestion to check out msceneNodes.Size(). It was being incremented and checking out msceneNodes._M_start, msceneNodes._M_start + 1, etc.. showed that the correct Node pointers were being added. Now onto figuring out why certain Nodes aren''t being displayed in my render loop...

Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
CWizard
CWizard
As a note, although you should [EDIT] NOT [/EDIT] concern yourself with the inner workings of the std::vector, I can tell you that _M_finish is most likely "pointing" to the end of the vector. That is, what some_vector.end() returns, and thus it never points to a valid object.

EDIT: a word got lost.




[edited by - CWizard on March 21, 2003 11:44:15 AM]
Mage2k
Mage2k
Yes, that was what the problem was. I was expecting it to point to the last object, not past it...
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
pdunstan
pdunstan
Looks like you already have your answer, but If you don't mind it like to suggest a change to simplify your addNode method.


      
#include <algorithm>

void SceneGraph::addNode(Node* _parent, Node* _child)
{
if (_parent == NULL)
{
_child->setParent(mrootNode);
msceneNodes.push_back(_child);
mrootNode->attachChild(_child);
}
else
{
//make sure _parent is in the graph

std::vector<Node*>::iterator it = std::find(msceneNodes.begin(), msceneNodes.end(), parent);
if (it != msceneNodes.end())
{
_child->setParent(_parent);
_parent->attachChild(_child);
msceneNodes.push_back(_child);
}
}
return;
}



--
Philip Dunstan
Independent Game Developer
phil@philipdunstan.com
http://www.philipdunstan.com/


[edited by - pdunstan on March 24, 2003 4:09:34 AM]

[edited by - pdunstan on March 24, 2003 4:10:09 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.