UPDATE: Bug is confirmed and reported. Thanks to Brian Kramer for his help.
I encountered some strange behaviour when using interior_ptr in a generic function. It appears that, for the purposes of pointer arithmetic, the byte size of the template parameter is always assumed to be 4, regardless of whether it is a char or a double. This doesn't happen when interior_ptr is given a concrete type directly.
The following example is a generic version of the online help example that demonstates the problem:
// interior_ptr bug example
// compile with: /clr
generic<typename T>
void ProbeFirstTwoElements(array<T>^ arr)
{
// create an interior pointer into the array
interior_ptr<T> ipi = &arr[0];
System::Console::WriteLine("1st element in arr holds: {0}", arr[0]);
System::Console::WriteLine("ipi points to memory address whose value is: {0}", *ipi);
ipi++;
System::Console::WriteLine("after incrementing ipi, it points to memory address whose value is: {0}", *ipi);
System::Console::WriteLine();
}
int main(array<System::String ^> ^args)
{
array<int>^ arrInt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
ProbeFirstTwoElements(arrInt);
array<double>^ arrDouble = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
ProbeFirstTwoElements(arrDouble);
array<char>^ arrChar = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
ProbeFirstTwoElements(arrChar);
return 0;
}
// Expected output:
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 2
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 2
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 2
//
// Actual output:
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 2
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 5.29980882362664E-315
//
// 1st element in arr holds: 1
// ipi points to memory address whose value is: 1
// after incrementing ipi, it points to memory address whose value is: 5
Most seriously, this bug has the potential for buffer overflows, even though the code might appear to pass various "correctness" tests.
No comments:
Post a Comment