Как сохранить адрес, на который указывает указатель? - PullRequest
3 голосов
/ 31 мая 2011

Я пытаюсь создать карту адресов объектов, которые я создаю со временем, в которое она выделена.Ключ - это адрес, возвращаемый при звонке на new().Как получить адрес, возвращаемый new()?

type T struct{a, b int }

func main(){

        var t int64 = time.Nanoseconds()
        memmap := make(map[uint8]int64)
        fmt.Printf("%d\n", t)
        var ptr *T = new(T)
        ptr.a = 1
        ptr.b = 2
        fmt.Printf("%d %d %p %T\n", ptr.a, ptr.b, ptr, ptr)
        //memmap[ptr] = t //gives error
        //var temp uint8 = ptr//gives error
}

Скажите, пожалуйста, какой должен быть тип поля ключа на карте, чтобы я мог сохранить адрес, возвращенный new()?Я планирую использовать new() с разными типами, получить выделенный адрес и сопоставить его со временем создания.

Ответы [ 2 ]

6 голосов
/ 31 мая 2011

Вы можете использовать тип Pointer из пакета unsafe, но это означает, что имя пакета является небезопасным. Сам адрес является непрозрачным, и в действительности использование только одного значения адреса для карты мало что дает, лучше использовать кортеж типа и адреса. Это то, что unsafe.Reflect предоставляет вам. Пакет reflect предлагает вам функцию UnsafeAddr и многое другое.

Предлагаю прочитать документацию к пакетам reflect и unsafe.

3 голосов
/ 31 мая 2011

Используйте uintptr , целое число без знака, достаточно большое для хранения неинтерпретированных битов значения указателя, в качестве типа ключа карты памяти.

Например,

package main

import (
    "fmt"
    "time"
    "unsafe"
)

type T struct{ a, b int }

func main() {
    memmap := make(map[uintptr]int64)

    pT := new(T)
    memmap[uintptr(unsafe.Pointer(pT))] = time.Nanoseconds()
    pT.a = 1
    pT.b = 2
    fmt.Printf("%d %d %p %T\n", pT.a, pT.b, pT, pT)

    pI := new(int)
    memmap[uintptr(unsafe.Pointer(pI))] = time.Nanoseconds()
    *pI = 42
    fmt.Printf("%d %p %T\n", *pI, pI, pI)

    fmt.Printf("\n%T\n", memmap)
    for k, v := range memmap {
        fmt.Printf("%x: %d\n", k, v)
    }
}

Выход:

1 2 0xf8400001f8 *main.T
42 0xf8400001f0 *int

map[uintptr] int64
f8400001f0: 1306837191421330000
f8400001f8: 1306837191421293000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...