成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

下一站“內存”:成為《黑客帝國》中的尼奧并不難

存儲 存儲軟件
Swift是一種內存安全語言。它限制用戶直接訪問內存,確保用戶在使用內存前已初始化所有內容。不安全的Swift API允許用戶通過指示器直接訪問內存。

本文轉載自公眾號“讀芯術”(ID:AI_Discovery)

你有沒有想過,尼奧深陷“母體”時是如何設法改變它的?

他又是如何把子彈從崔妮蒂身上清除的?顯然,“母體”只是機器編寫的一個程序,尼奧能在程序運行時更改程序的二進制代碼,并在矩陣中交換子彈的位置。

如果說,你們也可以這么做,也可以成為你程序中的尼奧,你會作何感想?我的意思是,或許各位很難與電影里的尼奧相匹敵,不過也差不多了。

程序運行過程中如何訪問和更改內存?使用Swift的不安全API就可以做到。

[[328712]]

什么是不安全?

Swift是一種內存安全語言。它限制用戶直接訪問內存,確保用戶在使用內存前已初始化所有內容。不安全的Swift API允許用戶通過指示器直接訪問內存。

或許不安全這個詞聽起來很糟糕,不過它并不意味著用戶代碼處于危險狀態且無法正常運行。Swift可以確保用戶不犯明顯錯誤。而使用不安全的API時,用戶必須時刻注意代碼的運行情況。尤其是在使用C、C++等語言時,這些API十分有用。

[[328713]]

圖源:unsplash

在弄清楚什么是不安全的Swift之前,需要先弄清楚什么是安全。

什么是內存安全?

想弄清楚這種情況,先來看幾個例子。

例1:使用年齡數組,嘗試在數組的第一個元素中加1。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

可以看到,這會出現錯誤,該值應與前面字符隔開。繼續嘗試。

這樣好像可以了。如果用空數組再試一次呢?

下一站“內存”:成為《黑客帝國》中的尼奧并不難

它崩潰了......再試試別的。

例2:嘗試查找年齡數組的平均值。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

它運行良好,就好像被施了魔法。不過空數組也能行嗎?

下一站“內存”:成為《黑客帝國》中的尼奧并不難

它又崩潰了......這次我們將試著訪問數組中的元素。

例3:嘗試訪問數組第3個和第4個索引處的元素。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

訪問第3個索引時,它可以正常運行,但訪問第4個索引時,它又雙崩潰了。

很明顯,如果嘗試任何異常操作,那么程序每次都會崩潰。如果崩潰是安全的,那......什么是不安全的?

想一下,假如你嘗試訪問數組中的年齡,而程序返回了一個負值,這種情況是不可能同時發生吧?可如果你嘗試獲取賬戶余額,程序返回的值是1000,而實際余額有2000,那該怎么辦?

沒錯,意外行為要危險得多。Swift提供了安全的API,從而讓用戶避免意外行為。深入了解不安全的API之前,先來看看內存和內存布局。

什么是內存?

在計算機中,內存以數字形式存儲,比如許多的“1”和“0”,我們稱之為比特。如果將這樣的內存可視化,會得到下面的圖像。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

二進制代碼

上圖呈現的是連續的比特流,代表實際數據。如果將每8個比特分為一組,那么這些比特組就是字節。如果將這些字節可視化,它們將如下圖所示。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

字節代碼

為便于理解,把它們轉換成十六進制代碼。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

十六進制代碼

如果繼續將每8個十六進制代碼分為一組,就會得到8字節或者是64比特的字。這也是當今全球使用的通用格式,構成了大部分設備的“64位系統”。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

字(64比特)

每個字都關聯一個地址,該地址也是十六進制數。每個內存地址之間都存在8個字節的差值,該差值剛好等于字的大小。該地址可用于訪問內存中該點的數據。

帶有內存地址的字

什么是內存布局?

這是一個Swift API,可在運行時告知用戶所提供類型的大小、對齊方式和跨度。

  • 大小:該類型所需的字節數。
  • 對齊方式:內存應是對齊方式的倍數。
  • 跨度:兩個元素之間的距離。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

內存布局Swift

嘗試一些代碼,以進一步了解內存布局API。這些是在64位操作系統計算機上運行該代碼所得到的值。

  1. MemoryLayout<Int>.size // returns 8 
  2. MemoryLayout<Int>.alignment // returns 8 
  3. MemoryLayout<Int>.stride // returns 8 
  4. MemoryLayout<Bool>.size // returns 1 
  5. MemoryLayout<Bool>.alignment // returns 1 
  6. MemoryLayout<Bool>.stride // returns 1 
  7. MemoryLayout<Double>.size // returns 8 
  8. MemoryLayout<Double>.alignment // returns 8 
  9. MemoryLayout<Double>.stride // returns 8 

什么是不安全的指示器?

不安全的指示器是Swift API的其中一種,它允許用戶訪問流中的數據或將數據與特定類型(如Int、Double等)綁定。與直接內存一起使用的類型,獲取“不安全”前綴。

下一站“內存”:成為《黑客帝國》中的尼奧并不難

Swift提供了8種類型的不安全指示器API,可根據實現特定目標的需要進行使用。

  • UnsafePointer
  • UnsafeMutablePointer
  • UnsafeRawPointer
  • UnsafeMutableRawPointer
  • UnsafeBufferPointer
  • UnsafeMutableBufferPointer
  • UnsafeRawBufferPointer
  • UnsafeMutableRawBufferPointer

為了更好地理解,來看一些例子。

例1:原始指示器

  1. let count = 2 
  2. let stride = MemoryLayout<Int>.stride 
  3. let alignment = MemoryLayout<Int>.alignment 
  4. let byteCount = stride * count //total number of byteslet pointer =UnsafeMutableRawPointer.allocate(byteCount: byteCount, alignment:alignment)defer { 
  5.   pointer.deallocate() 
  6. }pointer.storeBytes(of: 30, as: Int.self 
  7. pointer.advanced(by: stride).storeBytes(of: 3, as: Int.self) 
  8. pointer.load(as: Int.self) 
  9. pointer.advanced(by: stride).load(as: Int.self)let bufferPointer =UnsafeRawBufferPointer(start: pointer, count: byteCount)for (index, byte) inbufferPointer.enumerated() { 
  10.   print("byte \(index) ->\(byte)") 
  11. }// byte 0 -> 30 
  12. // byte 1 -> 0 
  13. // byte 2 -> 0 
  14. // byte 3 -> 0 
  15. // byte 4 -> 0 
  16. // byte 5 -> 0 
  17. // byte 6 -> 0 
  18. // byte 7 -> 0 
  19. // byte 8 -> 3 
  20. // byte 9 -> 0 
  21. // byte 10 -> 0 
  22. // byte 11 -> 0 
  23. // byte 12 -> 0 
  24. // byte 13 -> 0 
  25. // byte 14 -> 0 
  26. // byte 15 -> 0 
  • advanced用于按提供的跨度移動指示器。
  • UnsafeMutableRawPointer.allocate通過分配所需的類型返回可變的指示器。
  • UnsafeRawBufferPointer讓用戶以字節集合的方式訪問內存。用戶可對其進行迭代編輯來訪問字節。
  • storeByte會將提供的字節存儲在指定內存中,而load將通過與特定類型(此處為Int)綁定來加載數據。
  • ARC無法使用該API,用戶必須自行重新分配,因此,需要延遲代碼塊。每當指令從當前代碼塊返回時,它都將重新分配指示器。

例2:類型化的指示器

  1. let count = 2 
  2. let stride = MemoryLayout<Int>.stridelet pointer =UnsafeMutablePointer<Int>.allocate(capacity: count) 
  3. pointer.initialize(repeating: 0, count: count)defer { 
  4.   pointer.deinitialize(count: count) 
  5.   pointer.deallocate() 
  6. }pointer.pointee = 42 
  7. pointer.advanced(by: 1).pointee = 6let bufferPointer =UnsafeBufferPointer(start: pointer, count: count)for (index, value) inbufferPointer.enumerated() { 
  8.   print("value \(index) ->\(value)") 
  9. }// value 0 -> 42 
  10. // value 1 -> 6 
  • UnsafeMutablePointer.allocate為提供的計數分配T類型所需的字節數。
  • initialize將使用提供的值初始化指示器。
  • pointee可用于存儲、加載T類型的值。
  • advanced將指示器移至下一個字節。

不要做什么?

使用不安全的API時:

  • 一次只綁定一種類型(嘗試臨時綁定)
    1. let count = 3 
    2. let stride = MemoryLayout<Int16>.stride 
    3. let alignment = MemoryLayout<Int16>.alignment 
    4. let byteCount = count * stridelet pointer = UnsafeMutableRawPointer.allocate( 
    5.  byteCount: byteCount, 
    6.   alignment: alignment)let typedPointer1pointer.bindMemory(to: UInt16.self, capacity: count)// 911, someone isbreaking the Law 
    7. let typedPointer2 = pointer.bindMemory(to: Bool.self, capacity: count * 2)//Try this way instead 
    8. typedPointer1.withMemoryRebound(to: Bool.self, capacity: count * 2) { 
    9.   (boolPointer:UnsafeMutablePointer<Bool>) in 
    10.   print(boolPointer.pointee) 
  • 不要從withUnsafeBytes返回指示器(這樣做將來可能出現故障)
    1. struct ExampleStruct { 
    2.   let number: Int 
    3.   let flag: Bool 
    4. }var exampleStruct = ExampleStruct(number: 25, flag: true)let bytes = withUnsafeBytes(of:&exampleStruct) { bytes in 
    5.   return bytes // It may cause strangebugs anytime 
    6. }print("Here are are bytes to ruin your life", bytes) 
  • 不要盲目相信代碼(在代碼塊末尾檢查數據)
    1. let count = 3 
    2. let stride = MemoryLayout<Int16>.stride 
    3. let alignment = MemoryLayout<Int16>.alignment 
    4. let byteCount =  count * strideletpointer = UnsafeMutableRawPointer.allocate( 
    5.   byteCount: byteCount, 
    6.   alignment: alignment)let bufferPointerUnsafeRawBufferPointer(start: pointer, count: byteCount + 1) 
    7. // Putting it intentionally to cause an issue :pfor byte in bufferPointer { 
    8.   print(byte) // Check each byte 

學會這一招,快去你的程序中“遨游”吧!

 

責任編輯:趙寧寧 來源: 讀芯術
相關推薦

2011-09-05 17:11:51

2013-12-23 09:31:37

2015-12-10 09:47:37

2015-05-29 09:56:11

慧聰電子網

2009-01-16 22:37:44

2010-09-20 11:39:50

2012-02-07 09:25:43

移動市場Facebook

2022-11-24 08:00:00

2016-01-18 10:40:04

VRMR

2020-05-26 19:31:09

人工智能AI實時服務

2013-09-25 09:58:17

虛擬化網絡

2014-07-07 09:24:04

2013-05-29 09:51:16

BYODBYOD管理IT應用

2020-03-11 15:00:46

AI人工智能智能

2015-08-20 10:32:32

2009-08-28 17:58:16

2013-03-08 10:03:36

2010-08-11 11:40:06

云計算

2019-06-22 16:03:28

托管云計算企業

2014-01-10 16:33:17

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产综合久久久动漫日韩 | 日日骚网| 综合自拍 | 亚洲精品91 | 女女百合av大片一区二区三区九县 | 国产一级在线视频 | 国产偷录叫床高潮录音 | 国产高清在线精品一区二区三区 | 91精品久久久久久久久中文字幕 | 中文字幕1区 | 天天干狠狠操 | 欧美日韩免费在线 | 国产精品永久在线观看 | 欧美精品综合在线 | 99re99 | 91视频进入| 亚洲国产欧美一区二区三区久久 | 国产一级毛片视频 | www.五月天婷婷.com | 成人一区二区三区 | 亚洲品质自拍视频 | 亚洲一区二区三区桃乃木香奈 | 亚洲国产免费 | 日韩三级免费网站 | 欲色av | 国产成人精品一区二区三区四区 | 成人福利网 | 欧美性生活视频 | 91成人午夜性a一级毛片 | 精品91久久 | 国产精品视频免费观看 | 国产98色在线 | 日韩 | 99久久久久久久久 | 国产a区| 日韩视频在线一区 | 91精品国产自产在线老师啪 | 亚洲精品欧美一区二区三区 | 国产一区2区 | 麻豆91av| 日韩影院在线 | 精品国产乱码久久久久久闺蜜 |