日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 之不安全代码(2)

發布時間:2025/1/21 C# 64 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 之不安全代码(2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?? 固定的和活動的變量

&fixed將變量分為兩類:固定的和活動的。

固定的變量永久的存在并不會被GC的操作影響。(例如局部變量,值參數和間接指針)活動的變量會被GC重新分配位置或是釋放(例如對象中的字段,基礎數據數組)。

&取固定變量的地址是沒有限制的。但是活動變量容易受GC的影響,其地址只能通過fixed來獲得,并且地址僅會在整個fixed語句的周期持續有效。

靜態字段也是活動變量。還有標記為refout的也是活動變量,即使這個參數是傳遞給固定參數的。最后,通過間接指針引用的變量總是固定變量。

?

指針轉換

在不安全上下文中,下面的轉換是隱式的:

l? 從任何指針類型到void*

l? null到任何指針類型

除此之外,下面的轉換都是顯式的:

l? 從任何指針類型到另外的指針類型

l? sbyte, byte, short, ushort, int, uint, long, or ulong到其他類型

l? 從任何類型到sbyte, byte, short, ushort, int, uint, long, or ulong

指針轉換并不改變指針的值。也就是說指針轉換前后不影響地址的值。

當轉換發生后,當結果指針沒有按照正確的指針類型排列的話,當訪問結果時結果是無法預知的。

下面的例子:

?

1?char?c?=?'A';
2?char*?pc?=?&c;
3?void*?pv?=?pc;
4?int*?pi?=?(int*)pv;
5?int?i?=?*pi;????????//?undefined
6?*pi?=?123456;????????//?undefined
7?

?

?

下面的例子會打印出double8字節的值:

?

?1?using?System;
?2?class?Test
?3?{
?4?????unsafe?static?void?Main()?{
?5???????double?d?=?123.456e23;
?6?????????unsafe?{
?7????????????byte*?pb?=?(byte*)&d;
?8?????????????for?(int?i?=?0;?i?<?sizeof(double);?++i)
?9????????????????Console.Write("{0:X2}?",?*pb++);
10?????????????Console.WriteLine();
11?????????}
12?????}
13?}
14?

?

打印結果取決于endian

?

指針數組

在不安全上下文中,是允許指針數組的,只有幾種用于其轉換是允許的:

l? 從任何數組類型到System.Array或是實現了其接口的隱式引用類型轉換同樣適用于指針數組。但是,任何試圖通過System.Array或是實現了其接口訪問數組元素都會引發一個 運行時錯誤,因為指針類型不能轉化為object

l? 從一個一維數組類型S[]System.Collections.Generic.IList<T>或是到其基接口,任何顯示或是隱式的轉換都是不行的。因為指針類型不能被用作類型參數,還有沒有從指針類型到非指針類型的轉換。

l? System.Array或是實現了其接口到任何數組類型顯示引用轉換適用于指針數組。

l? System.Collections.Generic.IList<T>或是到其基接口到一個一維數組類型T[],任何顯示的轉換都是不行的。原因同上面第2條。

還有就是對于foreach語句,不適用于指針數組。相反,下面的語句

foreach (V v in x) embedded-statement

中的x是一個數組類型T[,,…,],n是數組的維度減1TV是指針類型,被改寫為:

{
????? T[,,…,] a = x;
????? V v;
????? for (int i0 = a.GetLowerBound(0); i0 <= a.GetUpperBound(0); i0++)
????? for (int i1 = a.GetLowerBound(1); i1 <= a.GetUpperBound(1); i1++)
????? …
????? for (int i
n = a.GetLowerBound(n); in <= a.GetUpperBound(n); in++) {
??????????? v
?= (V)a.GetValue(i0,i1,…,in);
??????????????????????????????? embedded-statement
????? }
}

變量a,i0,i1,…對于x或者embedded-statement或者其余部分的代碼是不可見的或是不可訪問的。變量vembedded-statement中是只讀的。如果沒有顯示轉換從TV,那么就會有錯誤。如果x是個null,就會有空引用異常。

?

表達式中的指針

在不安全上下文中,一個表達式的值可以來自于一個指針類型;但是在上下文之外,會造成編譯時期錯誤。

間接訪問

一元的*表示一個指針,被用來獲得指針指向的值。*用在void*類型表達式或是非指針類型表達式時,會造成編譯期錯誤。

*被用在null指針時是由實現來決定的。不能保證在使用時會拋出System.NullReferenceException

如果一個非法的值賦給指針,那么*的行為是不可預知的。

指針成員訪問

在指針成員訪問P->IP必須是除了void*之外的類型,I同時必須是一個可訪問的成員。

P->I效果上相同于(*P).I。例如:

?

using?System;
struct?Point
{
????
public?int?x;
????
public?int?y;
????
public?override?string?ToString()?{
????????
return?"("?+?x?+?","?+?y?+?")";
????}
}
class?Test
{
????
static?void?Main()?{
????????Point?point;
????????
unsafe?{
????????????Point
*?p?=?&point;
????????????p
->x?=?10;
????????????p
->y?=?20;
????????????Console.WriteLine(p
->ToString());
????????}
????}
}
或是:
class?Test
{
????
static?void?Main()?{
????????Point?point;
????????
unsafe?{
????????????Point
*?p?=?&point;
????????????(
*p).x?=?10;
????????????(
*p).y?=?20;
????????????Console.WriteLine((
*p).ToString());
????????}
????}
}

?

指針元素訪問

在指針元素訪問P[E]中,P必須是除了void*之外的類型,同時E必須能隱式的轉換為int, uint, long, or ulong的表達式。

P[E]效果上同*(P + E).例如:

?

?1?class?Test
?2?{
?3?????static?void?Main()?{
?4?????????unsafe?{
?5?????????????char*?p?=?stackalloc?char[256];
?6?????????????for?(int?i?=?0;?i?<?256;?i++)?p[i]?=?(char)i;
?7?????????}
?8?????}
?9?}
10?又如:
11?class?Test
12?{
13?????static?void?Main()?{
14?????????unsafe?{
15?????????????char*?p?=?stackalloc?char[256];
16?????????????for?(int?i?=?0;?i?<?256;?i++)?*(p?+?i)?=?(char)i;
17?????????}
18?????}
19?}
20?

?

總結

以上是生活随笔為你收集整理的C# 之不安全代码(2)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。