Fixed pointer instruction?

There is some code that I am reading, and part of it:

public static unsafe byte[] GetBytes(uint value, bool BigEndian) { byte[] buff = new byte[4]; fixed (byte* pbyte = buff)*((uint*)pbyte) = value; if (BigEndian) buff.EndianConvert(); return buff; } 

I understand that it just puts 4 bytes in the location of the device in an array of bytes, but I don’t understand how to do this.

My understanding of this is as follows:

 (byte* pbyte = buff) 

creates and returns a pbyte pointer byte that points to the buff address,

 (uint*)pbyte 

Pass pbyte address to uint ?,

I still don't get it. What is the use of the fixed keyword? Why it is impossible to do, for example:

 (byte* pbyte = buff) = (byte*)value; 
+4
source share
4 answers

Others explained the concept of fastening, but I think that you were confused by the fact that all this is on the same line.

 fixed (byte* pbyte = buff)*((uint*)pbyte) = value; 

It is equivalent to:

 fixed (byte* pbyte = buff) { *((uint*)pbyte) = value; } 

Just like this:

 if(someCondition) DoSomething(); 

It is equivalent to:

 if(someCondition) { DoSomething(); } 

It is clear? Now it should be obvious that the first part is the declaration of the variable and the block associated with it, and the second part is the assignment.

+1
source

The fixed statement prevents the garbage collector from moving the movable variable. if you omit it, your address may be changed and you will receive an error message

+2
source

You cannot just take the address of an array because it is controlled by the garbage collector, which means that its location in memory can change at any time. A fixed keyword puts the array in place for the duration of its scope, allowing four bytes of the array to be filled with the value (4 bytes) of uint.

+1
source

During the CLR GC process for ordinary GC heap objects (except for LOH), the GC will mark and move immovable objects to the next generation (this action is also called advanced). When promoting an A object, the GC changes the address of the object from addr-old to addr-new, and then updates the relationship of all objects that reference these objects.

For example, object A refers to object B and object C, which means that object B has a pointer that points to object A, and object C also has a pointer that points to object A. Then, in the progress phase, the address of object A will be changed from addr-old to addr-new, then GC will also change the value of the reference pointer of object B and object C. After the modification, objects B and C have the correct pointers, which are still pointed by A.

After executing the line "byte * pbyte = buff", pbyte has a pointer pointing to the object "buff", for example, the address pbyte is 0x12345678 (also means that the value of buff addr is 0x12345678). And now, the GC has occurred, the buff object will be upgraded to a new generation, which means that the buff object will have a new memory address, for example, 0x55555555. But "pbyte" is its own (unmanaged) object, the CLR does not know how to maintain its "life cycle", therefore, although pbyte is related to buff, the CLR cannot change the address of pbyte from 0x12345678 to 0x55555555. Then the pbyte pointer still points to the address 0x12345678, but this address does not refer to the buff object, the pbyte pointer is now a bad pointer.

The "fixed" operator ensures that the "buff" managed entity will not advance, and also means that it will not be moved from there to there.

0
source

Source: https://habr.com/ru/post/1388399/


All Articles