slice?俺知道,不就是基於數組的一個視窗嘛!golang
出個題唄~數組
好~安全
package mainide
func main() {函數
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}動畫
s := arr[2:6]ui
modify(s)編碼
}spa
func modify(tmp []int) {指針
// 實現該函數,把arr[8]的值修改成200
}
你千萬別告訴我是這樣實現的:
var point = &tmp[3]
point += 3
*point = 200
這樣作你真的可費瞎了心了 :)
由於golang指針不容許運算,像這樣會拋invalid operation: point += 3 (mismatched types *int and int)錯誤~~~
算了吧,仍是放着讓哥來
淺藍色的是slice當前的長度,整個藍色(淺藍色+深藍色)是slice的容量
站在從slice的視窗來看當前能看到{2,3,4,5},但若是擴大slice的容量就能夠看到{2,3,4,5,6,7,8,9},從slice的意義上來看,由slice能夠修改數組的arr[8]。
(1)獲取s[3]的地址,即arr[5]的地址
&s[3]
(2)把s[3]的地址轉換爲不安全的指針
unsafe.Pointer(&s[3])
(3)把s[3]不安全的指針轉換爲uint地址
uintptr(unsafe.Pointer(&s[3]))
(4)把指針向後移3個元素
var nextElement = uintptr(unsafe.Pointer(&s[3])) + 3 * 8 // 我怎麼知道每一個int佔8個字節,能夠用unsafe.Offsetof查看
(5)把目標元素的uint地址轉換爲不安全的指針
unsafe.Pointer(nextElement )
(6)把目標元素的不安全指針轉換爲地址
(*int)(unsafe.Pointer(nextElement ))
(7)修改目標元素的值
*(*int)(unsafe.Pointer(nextElement )) = 200
完整的程序以下:
package main
import "fmt"
import "unsafe"
func main() {
var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s := arr[2:6]
modify(s)
fmt.Println(arr)
}
func modify(tmp []int) {
var src = uintptr(unsafe.Pointer(&tmp[3]))
var dest = (*int)(unsafe.Pointer(src + 3*8))
*dest = 200
}
執行一下結果爲:
[0 1 2 3 4 5 6 7 200 9]
因此儘管只是slice了數組的一部分,而且沒有擴容,***者只是經過對slice的操做,依舊能夠攻到底層數組不可見的元素,從安全編碼角度來看,這是一個安全隱患 :)
關於slice的一些知識,我想作一個動畫,從視窗的維度再解釋一下。