Asked by:
Dereferencing a ref class from a vector.

Question
-
I have some pretty simple code:
int me = m_gridPos.y * m_gridWidth + m_gridPos.x; int mixPos = mixWith->m_gridPos.y * m_gridWidth + mixWith->m_gridPos.x;
(*m_grid)[mixPos] = this; (*m_grid)[me] = mixWith;
Now the grid is just a pointer to a vector with blocks in them. The block class is a ref class.
std::vector<Block^>* m_grid;
But, when I dereference the grid like I do above, it causes some strange exceptions quite complicated, and help?Thursday, October 18, 2012 2:40 AM
All replies
-
My exception occurs here:
__declspec(non_user_code) __declspec(no_refcount) __declspec(no_release_return) inline void* __abi_winrt_ptr_assign(void** __ppTargetArg, const volatile ::Platform::Object^ __objArg) { __abi_IUnknown* __pUnknown = reinterpret_cast<__abi_IUnknown*>(const_cast< ::Platform::Object^>(__objArg)); __abi_IUnknown** __ppTargetUnknown = reinterpret_cast<__abi_IUnknown**>(__ppTargetArg); if (__pUnknown != *__ppTargetUnknown) { if (__pUnknown) { __pUnknown->__abi_AddRef(); } if (*__ppTargetUnknown) { (*__ppTargetUnknown)->__abi_Release(); } *__ppTargetUnknown = __pUnknown; } return __pUnknown; }
Thursday, October 18, 2012 1:42 PM -
The code where the exception happens (__abi_winrt_ptr_assign function) is called when a ref pointer is assigned to another, like in the following code:
whateverObject ^pTarget, ^pSource; // ... pTarget = pSource; // This line calls __abi_winrt_ptr_assign(&pTarget, pSource);
Since pTarget and pSource are ref counted pointers, pSource ref count must be increased (__abi_AddRef() call in above code), and if pTarget is not null, pTarget ref count must be decreased (__abi_release() call in above code).
If an exception happens in this code, it means that one of the ref pointers are not valid. Check the pointer values. Both pSource AND pTarget MUST be valid pointers (or null).
IMHO it has nothing to do with the way you use the vector. Maybe "mixWith" is not a valid ref pointer. Or the vector already contains an invalid ref pointer.
- Edited by Pierre Morel-Fourrier Thursday, October 18, 2012 4:33 PM
- Proposed as answer by Pierre Morel-Fourrier Sunday, October 21, 2012 12:36 AM
Thursday, October 18, 2012 4:27 PM -
Hmmm... Very strange. I didn't have any problems with this until I changed the class into a ref class... I've checked them both and they seem to be valid.
This is the exception I'm getting.
Unhandled exception at 0x02E96B78 in Jungle Jam.exe: 0xC0000005: Access violation executing location 0x02E96B78.
At this point:
if (__pUnknown) { __pUnknown->__abi_AddRef(); }
I haven't got a clue what this means, but when looking into the __pUnknown, it contains a __vfptr with 3 elements. The first 2 elements look like valid pointers, but the third element is 0x00000000.
- Edited by DualOpAmp Monday, October 22, 2012 1:42 PM
Monday, October 22, 2012 12:47 PM -
I didn't have any problems with this until I changed the class into a ref class
Assigning standard C++ pointers is harmless even if the pointer is incorrect.
But ref pointers are not standard C++ pointers. They are "reference-counting smart pointers" (you can search for this expression on the web, or have a look at this MSDN page: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh699870.aspx). Smart pointers must be valid when you assign them, because their reference count is modified when they are assigned.
Monday, October 22, 2012 10:25 PM -
Well, how would I check if it's valid?Tuesday, October 23, 2012 2:20 AM
-
Try to use the pointer to your ref class: read and write some data members (access some class members). If you get an exception, then the pointer is not valid. If it works OK then the pointer should be valid.
If your pointer value is invalid, then you will have to start to find out why....
Tuesday, October 23, 2012 9:47 PM -
Well, I went through trying to access some member variables, and they seem to all be valid.
Another thing to note, some or maybe now ALL of the exceptions seem to be this:
Unhandled exception at 0x75854B32 (KernelBase.dll) in Jungle Jam.exe: 0x0000087D (parameters: 0x00000000, 0x02F5DAB8, 0x02F5CEF0).
The exception occurs in Spritebatch.cpp, here:
m_d3dContext->PSSetShaderResources(0, 1, &runIterator->textureView);
Quite strange, but this only occurs after the Mixup method. That's the method containing the code in the original post.Wednesday, October 24, 2012 12:10 AM -
I can't believe I didn't catch this before, I traced the__abi_winrt_ptr_assign() exception up through the call stack, and it originated at the PSSetShaderResource method. I think this is more of a graphics problem.
Okay, NVM. Another attempt reveals that it's still in the Mixup method.
void Block::MixUp(Block^ mixWith) { if (m_mixState == MixState::Static && mixWith->m_mixState == MixState::Static) { m_mixState = MixState::Mixing; mixWith->m_mixState = MixState::Mixing; int me = m_gridPos.y * m_gridWidth + m_gridPos.x; int mixPos = mixWith->m_gridPos.y * m_gridWidth + mixWith->m_gridPos.x; (*m_grid)[me] = mixWith; (*m_grid)[mixPos] = this; int x = m_gridPos.x; int y = m_gridPos.y; m_gridPos.x = mixWith->m_gridPos.x; m_gridPos.y = mixWith->m_gridPos.y; mixWith->m_gridPos.x = x; mixWith->m_gridPos.y = y; } }
- Edited by DualOpAmp Wednesday, October 24, 2012 12:34 AM
Wednesday, October 24, 2012 12:24 AM -
So, I think I have 2 problems.
Problem 1: The original post, to where calling the lines:
(*m_grid)[me] = mixWith; (*m_grid)[mixPos] = this;
Causes the __abi_winrt_ptr_assign() exception. Commenting out these lines fixes the problem, but of course limits functionality.
Problem 2: After Mixup has been called, there appears to be an error at spriteBatch->End(), here:
m_d3dContext->PSSetShaderResources(0, 1, &runIterator->textureView);
Friday, October 26, 2012 12:55 PM