-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Update unsafe code doc #47124
Changes from 6 commits
41110bd
7a036ec
070a7f9
c8868d9
20164ea
005c6a2
ae373c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ public static void Examples() | |
{ | ||
PointerTypes(); | ||
AccessEmbeddedArray(); | ||
UnsafeCopyArrays(); | ||
} | ||
|
||
private static void PointerTypes() | ||
|
@@ -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"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's not really any "interior pointers" used here. That term is typically reserved for More specifically, interior pointers are what allow What's being used here is just regular pointers with no special tracking support. The |
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only last? it's already bumped by +4 above. Not sure what exactly this loop is supposed to show - a bad/unreliable code example? |
||
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> | ||
} | ||
|
@@ -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> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the change to 1025?