Maison > développement back-end > Golang > Comment créer en toute sécurité une Go Slice à partir d'un pointeur de tableau sans copie de mémoire ?

Comment créer en toute sécurité une Go Slice à partir d'un pointeur de tableau sans copie de mémoire ?

Patricia Arquette
Libérer: 2024-12-07 10:03:15
original
522 Les gens l'ont consulté

How to Safely Create a Go Slice from an Array Pointer Without Memory Copying?

Création d'un tableau ou d'une tranche à partir d'un pointeur de tableau dans Golang

Dans Golang, création d'un tableau ou d'une tranche à partir d'un pointeur de tableau en utilisant unsafe. Le pointeur peut être difficile en raison de la copie de mémoire générée par les méthodes traditionnelles telles que memcpy ou Reflect.SliceHeader. Pour résoudre ce problème, nous discutons d'approches alternatives.

Avant-propos :

Avant d'approfondir les solutions, il est crucial de noter que l'utilisation des valeurs uintptr n'empêche pas le tableau d'origine d'être ramassés. Il est donc essentiel de faire preuve de prudence lors de la manipulation de ces valeurs, en s'assurant de leur validité avant d'y accéder. De plus, il est fortement recommandé de limiter l'utilisation du package non sécurisé, en donnant la priorité aux mécanismes de sécurité de type Go.

Solution utilisant Reflect.SliceHeader :

Une méthode efficace consiste à manipuler le reflet .SliceHeader descripteur d’une variable slice pour pointer vers le tableau souhaité. Cela implique de modifier ses champs Data, Len et Cap.

var data []byte

sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
sh.Data = p // Pointer to the array
sh.Len = size
sh.Cap = size

fmt.Println(data)
Copier après la connexion

En effectuant ces modifications, la variable de tranche de données pointe effectivement vers le même tableau que le pointeur initial.

Solution alternative utilisant un littéral composite :

Une autre approche consiste à créer un reflet.SliceHeader en utilisant un littéral composite, puis à le convertir à une tranche :

sh := &reflect.SliceHeader{
    Data: p,
    Len:  size,
    Cap:  size,
}

data := *(*[]byte)(unsafe.Pointer(sh))

fmt.Println(data)
Copier après la connexion

Cette méthode produit le même résultat que la solution précédente.

Mises en garde et avertissements :

Les solutions susmentionnées reposent en supposant que le tableau d'origine ne sera pas récupéré pendant que le pointeur est utilisé. Il est crucial de s'assurer que le fournisseur du pointeur garantit sa validité.

De plus, la documentation de unsafe.Pointer met explicitement en garde contre la déclaration ou l'allocation directe de variables de type structure réflexion.SliceHeader. Au lieu de cela, ils ne doivent être utilisés que comme pointeurs pointant vers de véritables tranches ou chaînes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal