7

is it possible to somehow cast the type of a pointer created by the fixed() statement?

This is the situation:

I have an array of byte, which i would like to iterate through, however i would like the values to be treated as int, thus having an int* instead of a byte*.

Here's some exemplary code:

byte[] rawdata = new byte[1024];

fixed(int* ptr = rawdata) //this fails with an implicit cast error
{
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}

Can this be done without having to do the cast inside the iteration?

2
  • 2
    Why you want to use pointers in C#? To iterate on this you can simple use for loop. Commented Jan 17, 2012 at 11:35
  • Agreed. Although adding your intent from the start helps provide answers and avoid questions :) Commented Feb 2, 2016 at 14:11

3 Answers 3

8
byte[] rawdata = new byte[1024];

fixed(byte* bptr = rawdata)
{
    int* ptr=(int*)bptr;
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You aren't actually moving your pointer, would probably be a good idea to show that. You should also mention the difference in byte size.
8

I believe you have to go via a byte*. For example:

using System;

class Test
{
    unsafe static void Main()
    {
        byte[] rawData = new byte[1024];
        rawData[0] = 1;
        rawData[1] = 2;

        fixed (byte* bytePtr = rawData)
        {
            int* intPtr = (int*) bytePtr;
            Console.WriteLine(intPtr[0]); // Prints 513 on my box
        }
    }
}

Note that when iterating, you should use rawData.Length / 4, not rawData.Length if you're treating your byte array as a sequence of 32-bit values.

2 Comments

What is the best way to process any remaining bytes with pointer arithmetic that do not divide evenly into sizeof(int)? (For example, if the byte array was 1023 bytes long.)
@QuickJoeSmith: I'd probably handle those not with pointer arithmetic, basically.
2

I found a - seemingly - more elegant and for some reason also faster way of doing this:

        byte[] rawData = new byte[1024];
        GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
        int* iPtr = (int*)rawDataHandle.AddrOfPinnedObject().ToPointer();
        int length = rawData.Length / sizeof (int);

        for (int idx = 0; idx < length; idx++, iPtr++)
        {
            (*iPtr) = idx;
            Console.WriteLine("Value of integer at pointer position: {0}", (*iPtr));
        }
        rawDataHandle.Free();

This way the only thing i need to do - apart from setting the correct iteration length - is increment the pointer. I compared the code with the one using the fixed statement, and this one is slightly faster.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.