MSVC 2010 strange behavior

Started by
5 comments, last by Misery 12 years ago
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=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 :]
Advertisement


[...]
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

[/quote]
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.
Sorry for putting something looking like a pseudo-code smile.png
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?
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.
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
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.
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 :]

This topic is closed to new replies.

Advertisement