Managed C++ silently ignores my array assignment

B

Ben Voigt

I am accustomed to using a pointer to traverse an array in native C++. Here
I am trying to copy a slice of a native 2-D array into a managed 2-D array
to make it accessible by C#. But piData isn't incremented and no value is
stored in m_aaSamples. Anyone know why?

m_aaSamples = new System::UInt16[BLOCK_SAMPLES,NUM_LEADS];
/* snip */
for( unsigned iLead = 0; iLead < NUM_LEADS; iLead++ ) {
short* piData = g_data + BUFFER_SAMPLES * iLead + BLOCK_SAMPLES *
g_nValid100msBlocks;
for( unsigned iSample = 0; iSample < BLOCK_SAMPLES; iSample++ ) {
m_aaSamples[iSample,iLead] = *(piData++);
}
}


Optimization is OFF. Disassembly with my best guess at what is happening:

(apparently esi is iLead and ebx is iSample)

m_aaSamples[iSample,iLead] = *(piData++);
000000c8 mov eax,ebx
000000ca mov edx,esi
000000cc mov ecx,dword ptr ds:[01B32608h] base of m_aaSamples
array descriptor, I think
000000d2 sub eax,dword ptr [ecx+10h] m_aaSamples lower
bound dim #0 I think
000000d5 cmp eax,dword ptr [ecx+8] m_aaSamples size
dim #0 I think
000000d8 jb 000000E1 always
hits, index bounds checking?
000000da xor ecx,ecx
ecx <= 0
000000dc call 75D5CF18 throw
ArrayIndexOutOfBoundsException?
000000e1 sub edx,dword ptr [ecx+14h] m_aaSamples lower
bound dim#1?
000000e4 cmp edx,dword ptr [ecx+0Ch] m_aaSamples lower
bound dim#1?
000000e7 jb 000000F0 always
hits, index bounds checking?
000000e9 xor ecx,ecx
ecx <= 0
000000eb call 75D5CF18 throw
ArrayIndexOutOfBoundsException?
000000f0 imul eax,dword ptr [ecx+0Ch] offset <= row *
COLUMNS
000000f4 add eax,edx
+ col
000000f6 mov edx,dword ptr [ebp-10h] read *piData?
000000f9 mov word ptr [ecx+eax*2+18h],dx index into m_aaSamples
based on offset and sizeof (short)

I cannot for the life of me figure out what happens to the post-increment!
Help!
 
G

Gary Chang[MSFT]

Hi Ben
But piData isn't incremented and no value is
stored in m_aaSamples. Anyone know why?

It appears to be a VC2003 compiler's issue, I performed some tests on my
side, there is no corresponding disassembly code to the pointer's
self-increment operation on the following code:

m_aaSamples[iSample,iLead] = *(piData++);

I suggest you split the piData pointer's self-increment operation into a
self-alone code to workaround this problem:

m_aaSamples[iSample,iLead] = *piData++;
piData++;


Thanks!

Best regards,

Gary Chang
Microsoft Community Support
--------------------
Get Secure! ¡§C www.microsoft.com/security
Register to Access MSDN Managed Newsgroups!
http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp
&SD=msdn

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Norman Diamond

It appears to be a VC2003 compiler's issue, I performed some tests on my
side, there is no corresponding disassembly code to the pointer's
self-increment operation on the following code:

m_aaSamples[iSample,iLead] = *(piData++);

I suggest you split the piData pointer's self-increment operation into a
self-alone code to workaround this problem:

That idea is theoretically valid as a temporary workaround, but your code is
dangerous:
m_aaSamples[iSample,iLead] = *piData++;
piData++;

Suppose someday Microsoft allows customers to get hotfixes, service packs,
or whatever it takes to get products closer to working as documented. Then
your code will increment piData twice. Maybe that's why Microsoft usually
doesn't let customers download hotfixes? Is it really recommended that
people should become dependent on Microsoft's bugs?

This particular case is lucky though. A safe workaround is possible:

m_aaSamples[iSample,iLead] = *piData;
piData++;
 
G

Gary Chang[MSFT]

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top