Since some days I am using MSVC 2013 and my application crashes when executing the following code (sparse matrix multiplied by vector, pseudo code: A = this * pVector):
complex<double> x = (A.getValue(lRow) + (mValues[lIdx] * pVectorB->getValue(lCol)));
Before I used MSVC 2005 and the application runs well.
The exception (First-chance exception at 0x000000014075D1D2 in psc64.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
) was thrown.
I track the assembly to:
addpd xmm6, xmmword ptr [rax+rbx*8]
It crash only with optimization /O2 (maximize speed) but not with no optimization /Od.
I can also avoid the crash when adding code (cout<<"bla bla") into the method pVectorB->getValue(lCol)
.
I believe it could be some problem with not initialized variables. But I could not find any. Therefore I look into the disassembly.
I check XMM6 and ptr [rax+rbx*8]. They are the same without crash (with cout<<"bla bla") and with crash.
Is there any thing more I should look for other then XMM6 and the value of ptr [rax+rbx*8]?
I am looking for the problem since quite some time but could not find any hint to track down the problem to the line of code I have to correct.
Any help is highly appreciated. Thank you.
The code for getValue:
template <class T> class Vector
{ const T& getValue(const int pIdx) const
{
if(false == checkBounds(pIdx)){
throw MathException(__FILE__, __LINE__, "T& Vector<class T>::getValue(const pIdx): checkBounds fails pIdx = %i", pIdx);
}
return mVal[pIdx];
}
bool checkBounds(const int pIdx)const
{
bool ret = true;
if(pIdx >= mMaxSize){
DBG_SEVERE2("pIdx >= mMaxSize, pIdx = %i, mMaxSize = %i", pIdx, mMaxSize);
ret = false;
}
if(pIdx < 0){
DBG_SEVERE1("pIdx < 0, pIdx = %i", pIdx);
ret = false;
}
return ret;
}
}
The allocation of mVal
:
void* lTmp= calloc((4 * sizeof(complex<double>))+4, 1);
((char*)lTmp)[0] = 0xC;
((char*)lTmp)[1] = 0xC;
((char*)lTmp)[(4 * sizeof(complex<double>)) + 2] = 0xC;
((char*)lTmp)[(4 * sizeof(complex<double>)) + 3] = 0xC;
mVal= (void*)(((char*)lTmp) + 2)
SOLUTION:
As suggested it works without the 2 byte in front and behind the desired array (mVal
). But it also works with multiple of 16byte before and after the array.