Jump to content

  • Log In with Google      Sign In   
  • Create Account


MSVC 2010 strange behavior


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Misery   Members   -  Reputation: 317

Like
0Likes
Like

Posted 26 April 2012 - 01:36 PM

Hello,

I have encountered quite strange problem. Making long story short:
I have a code:
[EDIT:]

	template <class DATA_TYPE,class INT_TYPE=std::size_t>
	class Matrix
	{
	   private:
		  INT_TYPE Rows, Cols;
		  DATA_TYPE *Data;	

	   public:
		 Matrix(); //basic constructor
		 Matrix(const Matrix<DATA_TYPE,INT_TYPE> &M); //copy cnstructor
		 ~Matrix(); //destructor

		 inline void Alloc(INT_TYPE _Rows,INT_TYPE _Cols);
		 inline void Free();
		 inline void Resize(INT_TYPE _Rows,INT_TYPE _Cols);
		 inline bool IsEmpty() const;

		 inline Matrix<DATA_TYPE,INT_TYPE>& operator =(const Matrix<DATA_TYPE,INT_TYPE>& M);
		inline Matrix<DATA_TYPE,INT_TYPE>& operator ()(const Matrix<INT_TYPE,INT_TYPE> &M) const;

		 inline void Fill(DATA_TYPE Value=DATA_TYPE());
		 inline void Copy(const Matrix<DATA_TYPE,INT_TYPE> &M);
		
	};  //CLASS DEFINITION END

	template <class DATA_TYPE,class INT_TYPE>
	inline Matrix<DATA_TYPE,INT_TYPE>::Matrix() //basic constructor
	{
		 Rows=0;
		 Cols=0;
		 Data=NULL;
	}

	template <class DATA_TYPE,class INT_TYPE>
	inline Matrix<DATA_TYPE,INT_TYPE>::Matrix(const Matrix<DATA_TYPE,INT_TYPE> &M) //copy constructor
	{
		 Rows=0;
		 Cols=0;
		 Data=NULL;
		Alloc(M.Rows,M.Cols);
		std::copy(M.Data,M.Data+NumOfElements(),Data);
	}


	template <class DATA_TYPE,class INT_TYPE>
	inline Matrix<DATA_TYPE,INT_TYPE>::~Matrix() //destructor
	{
		Free();
	}

	   template <class DATA_TYPE,class INT_TYPE>
	   inline Matrix<DATA_TYPE,INT_TYPE>& Matrix<DATA_TYPE,INT_TYPE>::operator =(const Matrix<DATA_TYPE,INT_TYPE>& M)  //Direct assignment operator
	   {
		  Copy(M);
		  return *this;
	   }

		template <class DATA_TYPE,class INT_TYPE>
		inline Matrix<DATA_TYPE,INT_TYPE>& Matrix<DATA_TYPE,INT_TYPE>::operator ()(const Matrix<INT_TYPE,INT_TYPE> &M) const
		{
		  INT_TYPE N=M.NumOfElements();
		  Matrix<DATA_TYPE,INT_TYPE> Returned;
		  if (Rows==1) Returned.Resize(1,N);
		  else Returned.Resize(N,1);
		  {
			  INT_TYPE i;
			   for (i=0;i<N;i++) Returned.Data[i]=Data[M.GetElement(i)];
		  }
   	   return Returned;
		}


When I use such a statement:
	Matrix<float,int> m,a;
	Matrix<int,int> ii;

	m.Resize(5,5);
	ii.Resize(3,1);
	ii(0)=0;
	ii(1)=1;
	ii(2)=2;
	a=m(ii);  //crashes VS2010, and returns an bad_alloc exception on VS2008, Intel Compiler works fine with it
const  Matrix<float,int> b=m(ii); //works fine

And trying to return the reference to some non const obect makes my PC suspend, VS2010 not responding and so on. Intel compiler or MSVC2008 runs with no problem at all. Is this normal for MSVC to behave this way? The problem is with reference. If operator () returns a copy everything works fine. But as I will use quite big objects I would like to avoid copying when necessary. But as far as I know if I use direct assignment operator with non const object (s2 here) it should automatically make a copy, but it suspends my PC.

In general, the code is taken without any change (except using template) from C++ for game programmers by MJ Dickheiser, so I assume that it should work.

Thanks & Regards :]

Edited by Misery, 27 April 2012 - 12:50 AM.


Sponsor:

#2 e‍dd   Members   -  Reputation: 2105

Like
1Likes
Like

Posted 26 April 2012 - 01:41 PM

[...]
inline SomeClass<A,B>& operator ()(const SomeClass<B,B> &M) const
{
  //blah blah
return SomeClass<A,B> ReturnInstance();
}
};

This doesn't even parse. Have you copy-pasted the code correctly?

When I use such a statement:

  SomeClass<int,int> ii;
  ii= some values
  SomeClass<float,int> s1,s2;
  s2 = some values, memry allocation for *Data using new etc
  s1=s2(ii); //this causes my PC suspend, and all RAM memory instantly full
  const   SomeClass<float,int> &s3=s2(ii);  //works fine

I would recommend that you post (a stripped-down version of) your actual code. The problem is just as likely in the part you conveniently(?) converted from C++ to English as it is anywhere else.

#3 Misery   Members   -  Reputation: 317

Like
0Likes
Like

Posted 27 April 2012 - 12:19 AM

Sorry for putting something looking like a pseudo-code Posted Image
I have edited the code. But strangely at work, I have VS2008 and it works in the meaning that debugger shows std::bad_alloc exception, but no PC suspend, so I assume that is just some issue...

I found out that when I use this syntax, Copy function doesn't work fine. The M matrix in Copy is undefined, and has random values. But Copy itself works well when
a.Copy(m)

is used, but fails for
a.Copy(m(ii))

The reason is that at the moment of m(ii) returning reference to temp object, this object disappears. But why? Shouldn't it be automatically copied?

#4 SiCrane   Moderators   -  Reputation: 9501

Like
1Likes
Like

Posted 27 April 2012 - 07:45 AM

In C++ local variables are always destroyed when program flow leaves the scope they were defined in. Unless you do the copy in that scope, it will be destroyed before the copy is made. The primary difference between compilers in this regard is exactly what they do when they destroy the objects. MSVC's debug mode will fill deleted memory with bit patterns that are likely to generate access violations. This makes it clear that you did something non-kosher like access memory previously owned by a now deleted object.

#5 Misery   Members   -  Reputation: 317

Like
0Likes
Like

Posted 27 April 2012 - 09:06 AM

I did what I wanted using a function
Choose(const Matrix<DATA_TYPE,INT_TYPE>& From, const Matrix<INT_TYPE,INT_TYPE> &Which,Matrix<DATA_TYPE,INT_TYPE> &To)

that chooses the elements and writes with indices given in Which. But I, thought I'll be able to use nice, elegant OO code, even more, because I found it in a book. And to be honest, the exact example from the book works, but it is slightly different.

Thanks for help and
Regards

#6 SiCrane   Moderators   -  Reputation: 9501

Like
0Likes
Like

Posted 27 April 2012 - 12:58 PM

Incidentally, this is probably a sign that you aren't paying enough attention to compiler warnings. Returning a reference to a local or temporary is a level 1 warning in MSVC, which means that if you have warnings enabled at all it should complain when you do something like this.

#7 Misery   Members   -  Reputation: 317

Like
1Likes
Like

Posted 28 April 2012 - 03:57 AM

I admit, that I did not care about this warning, because I wanted to use technique described in C++ for game programmers. There is a statment, that says, it should automatically create a copy of an object but there it didn't point to really temporary object. I misunderstood the example i guess. Anyways, I've learned something new and that is important :]

Edited by Misery, 28 April 2012 - 04:06 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS