Skip to content

Update unsafe code doc #47124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public class ClassConvert
public static void Conversions()
{
// <SnippetConversion>
int number = 1024;
int number = 1025;

unsafe
{
Expand All @@ -23,8 +23,8 @@ public static void Conversions()
System.Console.WriteLine($"The value of the integer: {number}");

/* Output:
The 4 bytes of the integer: 00 04 00 00
The value of the integer: 1024
The 4 bytes of the integer: 01 04 00 00
The value of the integer: 1025
*/
}
// </SnippetConversion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public static void Examples()
{
PointerTypes();
AccessEmbeddedArray();
UnsafeCopyArrays();
}

private static void PointerTypes()
Expand All @@ -20,38 +19,47 @@ private static void PointerTypes()
// Must pin object on heap so that it doesn't move while using interior pointers.
fixed (int* p = &a[0])
{
// p is pinned as well as object, so create another pointer to show incrementing it.
Console.WriteLine("Print first two elements using interior pointers:");
Console.WriteLine(*p);
// p and its container object a are pinned
// The fixed pointer (p) cannot be incremented directly
// Another pointer is required for incrementing
int* p2 = p;
Console.WriteLine(*p2);
// Incrementing p2 bumps the pointer by four bytes due to its type ...
// Increment the p2 pointer by the size of one int
p2 += 1;
Console.WriteLine(*p2);
p2 += 1;
// Increment the p2 pointer by the size of three ints (to the last element)
p2 += 3;
Console.WriteLine(*p2);
Console.WriteLine("--------");
Console.WriteLine(*p);
// Dereferencing p and incrementing changes the value of a[0] ...
*p += 1;
Console.WriteLine(*p);
*p += 1;
Console.WriteLine(*p);
Console.WriteLine("Increment each element by 5 using interior pointers");
for (int i = 0; i < a.Length; i++)
{
// p3 will reference past the end of the loop on the last iteration
// a good reason to keep it private to the loop
int* p3 = p + i;
*p3 += 5; // Increment the value at the pointer
}
}
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);
Console.WriteLine("Print final values:");
foreach (var item in a)
{
Console.WriteLine(item);
}

/*
Output:
/* Output:
Print first two elements using interior pointers:
10
20
30
--------
10
11
12
--------
12
50
Increment each element by 5 using interior pointers
Print final values:
15
25
35
45
55
*/
// </Snippet5>
}
Expand Down Expand Up @@ -96,101 +104,4 @@ private static void AccessEmbeddedArray()
}
}
// </Snippet7>

// <Snippet8>
static unsafe void Copy(byte[] source, int sourceOffset, byte[] target,
int targetOffset, int count)
{
// If either array is not instantiated, you cannot complete the copy.
if ((source == null) || (target == null))
{
throw new System.ArgumentException("source or target is null");
}

// If either offset, or the number of bytes to copy, is negative, you
// cannot complete the copy.
if ((sourceOffset < 0) || (targetOffset < 0) || (count < 0))
{
throw new System.ArgumentException("offset or bytes to copy is negative");
}

// If the number of bytes from the offset to the end of the array is
// less than the number of bytes you want to copy, you cannot complete
// the copy.
if ((source.Length - sourceOffset < count) ||
(target.Length - targetOffset < count))
{
throw new System.ArgumentException("offset to end of array is less than bytes to be copied");
}

// The following fixed statement pins the location of the source and
// target objects in memory so that they will not be moved by garbage
// collection.
fixed (byte* pSource = source, pTarget = target)
{
// Copy the specified number of bytes from source to target.
for (int i = 0; i < count; i++)
{
pTarget[targetOffset + i] = pSource[sourceOffset + i];
}
}
}

static void UnsafeCopyArrays()
{
// Create two arrays of the same length.
int length = 100;
byte[] byteArray1 = new byte[length];
byte[] byteArray2 = new byte[length];

// Fill byteArray1 with 0 - 99.
for (int i = 0; i < length; ++i)
{
byteArray1[i] = (byte)i;
}

// Display the first 10 elements in byteArray1.
System.Console.WriteLine("The first 10 elements of the original are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray1[i] + " ");
}
System.Console.WriteLine("\n");

// Copy the contents of byteArray1 to byteArray2.
Copy(byteArray1, 0, byteArray2, 0, length);

// Display the first 10 elements in the copy, byteArray2.
System.Console.WriteLine("The first 10 elements of the copy are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray2[i] + " ");
}
System.Console.WriteLine("\n");

// Copy the contents of the last 10 elements of byteArray1 to the
// beginning of byteArray2.
// The offset specifies where the copying begins in the source array.
int offset = length - 10;
Copy(byteArray1, offset, byteArray2, 0, length - offset);

// Display the first 10 elements in the copy, byteArray2.
System.Console.WriteLine("The first 10 elements of the copy are:");
for (int i = 0; i < 10; ++i)
{
System.Console.Write(byteArray2[i] + " ");
}
System.Console.WriteLine("\n");
/* Output:
The first 10 elements of the original are:
0 1 2 3 4 5 6 7 8 9

The first 10 elements of the copy are:
0 1 2 3 4 5 6 7 8 9

The first 10 elements of the copy are:
90 91 92 93 94 95 96 97 98 99
*/
}
// </Snippet8>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public static void PointerExamples()

// <InvokeViaFunctionPointer>
int product = 0;
static int localMultiply(int x, int y) => x * y;
unsafe
{
static int localMultiply(int x, int y) => x * y;
product = UnsafeCombine(&localMultiply, 3, 4);
}
// </InvokeViaFunctionPointer>
Expand Down
Loading