I rewrite code from C to C #. Faced the following problem.

Here's the code for si.

int right[2 * par - 1]; int left[2 * par - 1]; ... void func() { int *p; // some code if (k & mask) p = &right[*p]; else p = &left[*p]; } 

And here is my version in C #.

 int[] right = new int[2 * par - 1]; int[] right = new int[2 * par - 1]; ... unsafe void func() { int *p; //some code if ((k & mask) != 0) p = &right[*p]; else p = &left[*p]; } 

In if VS produces the following error

The address of an unfixed expression can be obtained only inside the initializer of the fixed statement

I do not understand how to solve the problem using this operator. Help to understand, please.

PS using the fixed operator, as shown in the example from msdn , did not work, because in that example it is necessary to write an int *p = &variable construct in parentheses, and I already have int *p in the beginning of the code, and in the process it is successfully assigned and changed, but when it comes to if , an error occurs.

  • I freaked out) is, but such a rarity and moveton to use them in c # - PavelNewSky
  • I understand, and yet I would like to understand how to solve the problem. - Setplus
  • So actually, this question is: how to use it right here - Setplus
  • yes, something I just started up, apparently today ... attach to the question how you tried it and why it didn't work out, please - PavelNewSky

2 answers 2

To rewrite this code in C # head-on is not the best idea.

In fact, in this code, the p pointer is used to immediately indicate an array and its element. And since C # doesn’t do that, you can return to full form:

 int[] parray; int pindex; //some code if ((k & mask) != 0) { int v = parray[pindex]; // Ранее *p parray = right; pindex = v; } else { int v = parray[pindex]; // Ранее *p parray = left; pindex = v; } 

If there is a lot of such code, you can help yourself with a structure that will behave like a pointer to an array cell:

 struct ArrayCell<T> { private readonly T[] array; private readonly int index; public ArrayCell(T[] array, int index) { this.array = array; this.index = index; } public T Value { get { return array[index]; } set { array[index] = value; } } } static class ArrayCellExtensions { public static ArrayCell<T> Cell<T>(this T[] array, int index) => new ArrayCell<T>(array, index); // Немного сахара } // ... ArrayCell<int> p; //some code if ((k & mask) != 0) p = right.Cell(p.Value); else p = left.Cell(p.Value); 
  • To be honest, I don’t really understand how the string int v = parray[ pindex] ... works - Setplus
  • @Setplus and what is incomprehensible to the element of the array? - Pavel Mayorov
  • what goes to the array element ... through an array variable ... - Setplus
  • @Setplus and what is wrong? Why left does not confuse you, and parray - confuses? - Pavel Mayorov
  • Instead of struct ArrayCell<T> you can use the ref keyword (Reference local variables) —Andrey NOP

Here are two options, if arrays are created and live inside a function, and their size is small, you can select them on the stack:

 int* right = stackalloc int[2 * par - 1]; ... if ((k & mask) != 0) p = &right[*p]; 

In your case, this is not ok, because you have a variable array size, you can run into StackOverflow); Option two, fix location in memory:

  fixed (int* _right = &right[0], _left = &left[0]) { ... if ((k & mask) != 0) p = &_right[*p]; } 

You can work with array pointers only inside the fixed block. You can cheat and write something like:

 if ((k & mask) != 0) fixed(int* ptr = &right[*p]) { p = ptr; } 

but the very first garbage collection can move data anywhere and the pointer will no longer be valid.

ps you have a problem not in the assignment of p and not in if, but in an attempt to take the address of an array that is not fixed in memory.