Advertisement

Pointers behaving strange!?

Started by May 02, 2001 04:59 PM
9 comments, last by Snale 23Β years, 9Β months ago
I am working on a mesh class and has encountered some weird problems. The vertices are stored in a vector and the triangles in another. Each triangle has three pointers to vertex objects in the first vector. Each vertex object has a vector containing pointers to all triangles that makes use of it. The problem occurs when I try to do this, vertices[24].parenttriangels[4]->A The Triangle''s first pointer is completely bogus while the two others are right. Whats really confusing though is that that pointer actually is right earlier in the program. And I don''t touch these pointers between these two occasions. What seems to have happened is that some pointers actually has changed sponataneously without me touching them. Have checked my code at least 25 times the last two weeks and I just can''t find the problem... HEEEEELP, I''m getting desperate Snale +--My humble and superior homepage
it would help if you post some code, but i can take a shot at it. Is it possible that the pointers are being passed into a function, modified there (and they are right when you check them there), then when the function exits they aren''t right anymore?

Here is an example of this problem. The char *pig is modified in the function, but the modification is lost due to the pass by value nature of C.

i hope this helps.

int main() {
char *pig;
makestring(pig);
// line below won''t print what you want
printf("After the call, the string is: %s\n", pig);
}

makestring(char *astring) {
astring = (char *) malloc(sizeof(char)*8);
sprintf(astring, "the_pig");
printf("Here is the string: %s\n", astring);
}
Advertisement
Just to let anyone know who cant figure out why kiev_class''s code in his post wont work like you want is because the function should use double indirection in the paramater list. Which means makestring( char **astring ). Then in makestring every time you access astringm like when you do the malloc and sprintf, you should put a * before astring. Just thought id share that.

-SirKnight
thanks SirKnight. That was stupid of me to omit the right answer.
Well... the problem isn''t something like that. The problem is that one pointer changes, while the others remain intact but I do the same thing with all of them...

some source, don''t know if this helps. Everything needed to understand the problem should be there, but I can post some more if needed.

  class Vertex	{		public:			//-Variables---------------------------------------------			VECTOR	p;								//Coordinates			VECTOR	n;								//Normal						Color	c;								//Color						float	cost;			Vertex*	lodId;						std::vector<Triangle<Vertex> *> 	parents;		//List of triangles it is a part of			std::vector<Vertex *>				neighbors;		//List of adjacent vertices							//-Constructors------------------------------------------						Vertex();			Vertex( VECTOR v, Color C = Color() );					Vertex( VECTOR v1, VECTOR v2, Color C = Color() );				//-Member Functions--------------------------------------			void addParent( Triangle<Vertex> *T );		//	Adds a parent triangle.			void removeParent( Triangle<Vertex> *T );	// 	Removes parent triangle, possibly unnessecary			void addNeighbor( Vertex * V );				// 	Adds adjacent triangle.			void calcCost();							// 	Calculates cost of collapsing.			void calcNormal();							//	Crashes after a while, pointers get screwed up somewhere?!			void collapse();							// 	Collapses Vertex to the position of lodID.			void uncollapse();							// 	Undo the changes by collapse()				//-Operators---------------------------------------------			void operator=( const Vertex &V );						friend bool operator==( Vertex V1, Vertex V2 );			friend istream& operator>>( istream ∈, Vertex &V );			friend ostream& operator<<( ostream &out, Vertex &V );	};	template<class _Ty>	class Triangle	{		public:			//-Variables---------------------------------------------						_Ty		*A; 			_Ty		*B;			_Ty		*C;			bool	draw;			//-Constructors------------------------------------------						Triangle( _Ty *a, _Ty *b, _Ty *c ) 	{ A = a; B = b; C = c; }									//-Member Functions--------------------------------------			void setVertex( _Ty *V, _Ty *T )	//	Sets the vertex *V to *T			{				draw = true;				if( A == V )					A = T;				else if( B == V ) 					B = T;				else					C = T;				if( A == B || A == C || B == C )					draw = false;			}	};void Mesh::addTriangle( unsigned int a, unsigned int b, unsigned int c )	{		assert( ( a > 0 || a <= vertices.size() ) && ( b > 0 || b <= vertices.size() ) && ( c > 0 || c <= vertices.size() ) ); 		Triangle<Vertex> T( &vertices[a], &vertices[b], &vertices[c] );		triangles.push_back( T );		Triangle<Vertex> *ptr = triangles.end(); 		vertices[a].addParent( ptr );		vertices[b].addParent( ptr );		vertices[c].addParent( ptr );				vertices[a].addNeighbor( &vertices[b] );		vertices[a].addNeighbor( &vertices[c] );		vertices[b].addNeighbor( &vertices[a] );		vertices[b].addNeighbor( &vertices[c] );		vertices[c].addNeighbor( &vertices[a] );		vertices[c].addNeighbor( &vertices[b] );			flog << "Added triangle at: 0x" << triangles.end() << " {\n\tVertex: " << a << "\tat: 0x" << &vertices[a] << "\n\tVertex: " << b << "\tat: 0x" << &vertices[b] << "\n\tVertex: " << c << "\tat: 0x" << &vertices[c] << "\n}\n";		//flog << "0x" << triangles.end() << "\t0x" << vertices[a].neighbors.end() << "\t0x" << vertices.neighbors.end() &lt;&lt; "\t0x" &lt;&lt; vertices[c].neighbors.end() &lt;&lt; ''\n'';<br></font><br>	<font color="gray">//All pointers right at this point<br></font><br>        }<br><br><font color="blue">void</font> Vertex::calcNormal()<br>	{<br>		VECTOR avgnormal;<br><br>		flog &lt;&lt; <font color="darkred">"Number of parents: "</font> &lt;&lt; parents.size() &lt;&lt; ''\n'';<br>		<font color="blue">for</font>( <font color="blue">unsigned</font> <font color="blue">int</font> i = 0; i &lt; parents.size(); i++ )<br>		{<br>			<font color="gray">//Some pointers wrong here, but not all.. <br></font><br>                        flog &lt;&lt; i &lt;&lt; <font color="darkred">"\t0x"</font> &lt;&lt; parents[<font color="purple">i</font>] &lt;&lt; <font color="darkred">"\t0x"</font> &lt;&lt; parents[<font color="purple">i</font>]-&gt;A &lt;&lt; <font color="darkred">"\t0x"</font> &lt;&lt; parents[<font color="purple">i</font>]-&gt;B &lt;&lt; <font color="darkred">"\t0x"</font> &lt;&lt; parents[<font color="purple">i</font>]-&gt;C &lt;&lt; ''\n'';<br>			avgnormal = avgnormal + (parents[<font color="purple">i</font>]-&gt;A-&gt;p - parents[<font color="purple">i</font>]-&gt;B-&gt;p) * (parents[<font color="purple">i</font>]-&gt;C-&gt;p - parents[<font color="purple">i</font>]-&gt;B-&gt;p);<br>		}<br>		<br>		avgnormal.y *= -1;<br>		n = avgnormal / (float)(neighbors.size() - 1) + p;<br>		n = n / n.length();<br>	} <br><br>ifstream& operator&gt;&gt;( ifstream &in, Mesh &mesh )<br>	{<br>		<font color="blue">int</font> nVertex = 0;<br>		<font color="blue">int</font> nTriangles = 0;<br>		<font color="blue">unsigned</font> <font color="blue">int</font> triangle[<font color="purple">3</font>];<br>		Vertex V;<br><br>		mesh.vertices.clear();<br>		mesh.triangles.clear();<br>		mesh.lodTable.clear();<br>		<br>		in.read( (<font color="blue">char</font> *)&nVertex, <font color="blue">sizeof</font>(nVertex) );<br>		in.read( (<font color="blue">char</font> *)&nTriangles, <font color="blue">sizeof</font>(nTriangles) );<br>		<br>		<font color="blue">for</font>( <font color="blue">int</font> i = 0; i &lt; nVertex; i++ )<br>		{<br>			in &gt;&gt; V;<br>			mesh.addVertex(V);<br>			flog &lt;&lt; &mesh.vertices[<font color="purple">i</font>] &lt;&lt; ''\n'';<br>		}<br><br>		flog &lt;&lt; <font color="darkred">"-&gt; Beginning of triangle data. \n"</font>;<br><br>		<font color="blue">for</font>( <font color="blue">int</font> j = 0; j &lt; nTriangles; j++ ) <br>		{<br>			in.read( (<font color="blue">char</font> *)triangle, <font color="blue">sizeof</font>(<font color="blue">unsigned</font> int) * 3 );<br>			mesh.addTriangle( triangle[<font color="purple">0</font>], triangle[<font color="purple">1</font>], triangle[<font color="purple">2</font>] );<br>		}<br><br>		<font color="blue">for</font>( <font color="blue">unsigned</font> <font color="blue">int</font> k = 0; k &lt; mehs.vertices.size(); k++ )<br>		{<br>			flog &lt;&lt; <font color="darkred">"-&gt; "</font> &lt;&lt; k &lt;&lt; <font color="darkred">" 0x"</font> &lt;&lt; &mesh.vertices[<font color="purple">k</font>] &lt;&lt; <font color="darkred">" &lt;β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”\n"</font>;<br>			mesh.vertices[<font color="purple">k</font>].calcNormal();<br>		}<br><br>		mesh.calcLod();<br><br>		mesh.setLod(0.0f);<br><br>		<font color="blue">return</font> in;<br>	}<br>  </pre></font></td></tr></table></center><!–ENDSCRIPT–>     <br><br>Snale<br>+–<A href="http://www.snale.f2s.com">My humble and superior homepage</A>    
The vectors you show have only pointers on them, but do you have other vectors that have objects on them instead of pointers? When you insert a new item into a vector, it reshuffles the contents to make room for the new item. If your objects themselves contain pointers, when it gets copied to the new location (uses the assignment operator or copy constructor), weird things happen for the pointer members. The pointer gets deleted by the destructor at the old location, but it just copies the pointer value to the new location, so you end up with an invalid pointer. This one bites me alot. Don''t know if that is your problem or not but based on the symptoms you describe it certainly sounds like it. Just a thought

Advertisement
Wait. I think I see it.

You have this code:

triangles.push_back( T );
Triangle *ptr = triangles.end();

You should use triangles.back() instead. the end() is just a placeholder and isn''t a real object with a real pointer that you can use like that.

Hope that helps
Thanks
Have to test that...
Started to convert my code into using indexes instead, but that would require an almost complete redesign of everything so I''m more or less stuck with what I have

Snale
+--My humble and superior homepage
Whoohoo..
That solved 9 of 10 problems..
Thanks a lot.
vector::end() returns a iterator, right?
should have thought about that..

Snale
+--My humble and superior homepage

Edited by - snale on May 4, 2001 11:10:28 AM
I noticed that the vector class sometimes moves data around when you add things to it, even with push_back, to avoid fragmentation and ensure faster access (I suppose).
So I solved the last few problems by simply adding everything before retrieving the pointers.

Snale
+--My humble and superior homepage

This topic is closed to new replies.

Advertisement