1 回答

TA貢獻1807條經驗 獲得超9個贊
因為buf是切片(不是數組),切片只是描述符。
您很可能想寫入分配字節的內存空間,因此不要使用切片描述符的地址,而是使用分配字節的地址,您可以通過獲取第一個元素的地址來獲得(切片描述底層數組的連續部分):
t := (*Point)(unsafe.Pointer(&buf[0]))
輸出(在Go Playground上試試):
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[10 0 0 0 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
正如你可以看到,可以設置數據出現在第二輸出(10 0 0 0是4個字節的int值10,100 0 0 0是4個字節的int值100)。
如果您使用切片描述符的地址,您會看到恐慌,因為描述符包含諸如第一個元素的地址、元素計數和容量之類的內容。因此,通過使用描述符的地址,您將修改這些地址,并且在嘗試將其作為切片再次打印時,您寫入的數據很可能位于無效指針中。您可以通過寫入十六進制值來確認10這一點0xa,并且錯誤消息包含:addr=0xa
另一種選擇是使用“真實”數組而不是切片,因為數組不是描述符:
buf := [50]byte{}
t := (*Point)(unsafe.Pointer(&buf))
有了這個改變,輸出將是相同的。
- 1 回答
- 0 關注
- 199 瀏覽
添加回答
舉報