La gestion de la mémoire est l’un des points forts de Rust, d’autant plus que la sécurité n’est pas compromise. Le système de propriété de Rust permet au compilateur de garantir la sécurité du code et l’absence d’erreurs de mémoire comme les pointeurs pendants et les fuites de mémoire.
Rust fournit également des pointeurs intelligents avec des métadonnées et des capacités supplémentaires par rapport aux pointeurs traditionnels. Les pointeurs intelligents sont pratiques pour lutter contre les fuites de mémoire.
Que sont les pointeurs intelligents en Rust ?
Les pointeurs intelligents sont l’un des types de données de Rust qui étendent les capacités des pointeurs ordinaires en offrant des fonctionnalités supplémentaires telles que des opérateurs surchargés, des destructeurs et une gestion automatique de la mémoire.
Rust utilise des structs pour exécuter les pointeurs intelligents ; ainsi, les pointeurs intelligents ont également des capacités de propriété.
Lorsque vous liez la mémoire contenant des données allouées dynamiquement avec des pointeurs intelligents, ceux-ci sont automatiquement désalloués. Les pointeurs intelligents permettent de contrôler la durée de vie des objets de Rust, ce qui les rend pratiques pour éviter les erreurs telles que le déréférencement de pointeurs nuls et les fuites de mémoire qui sont populaires dans d’autres langages de bas niveau comme le C et le C++.
Avantages de l’utilisation des pointeurs intelligents
Voici quelques avantages de l’utilisation des pointeurs intelligents :
- Gestion automatique de la mémoire: Les pointeurs intelligents permettent une gestion automatique de la mémoire, y compris l’allocation et la désallocation, contrairement à la gestion manuelle de la mémoire avec les pointeurs ordinaires.
- Sécurité améliorée: Les pointeurs intelligents appliquent la sémantique de propriété, garantissant qu’un seul propriétaire peut accéder aux ressources à la fois, évitant ainsi les traces de données et les bogues liés à la concurrence.
- Flexibilité: Rust fournit plusieurs pointeurs intelligents, chacun avec son propre ensemble de sémantiques de propriété pour écrire du code sûr de manière flexible.
- Gestion des ressources: Vous pouvez utiliser des pointeurs intelligents pour gérer d’autres ressources telles que des gestionnaires de fichiers et des sockets réseau en encapsulant les ressources dans un pointeur intelligent qui facilite la gestion de leur cycle de vie et garantit qu’elles sont correctement fermées et libérées après utilisation.
- Amélioration des performances: Les pointeurs intelligents permettent d’améliorer les performances en réduisant la copie et l’allocation de mémoire. La réduction de l’empreinte mémoire due à l’utilisation de pointeurs intelligents se traduit par une amélioration des performances.
Les pointeurs intelligents conviennent aux applications de taille moyenne à grande, en particulier dans les cas où la gestion de la mémoire est essentielle.
Types de pointeurs intelligents
Rust fournit plusieurs types de pointeurs intelligents, notamment Boîte, Rc, RefCellet Mutex.
1. La boîte Smart Pointer
La Boîte Smart Pointer est le pointeur intelligent le plus simple et le plus courant de Rust. Le pointeur Boîte Le pointeur intelligent permet d’allouer des valeurs sur le tas et de créer un pointeur en boîte pour l’accessibilité.
Le pointeur Boîte Le pointeur intelligent est pratique pour l’allocation dynamique de mémoire lorsque vous devez vous assurer que la mémoire est automatiquement désallouée lorsque les pointeurs sont hors de portée.
Voici comment vous pouvez déclarer et utiliser un Boîte pointeur :
fn main(){
// new instance of the box smart pointer
let x = Box::new(5);
println!(x)
}
Le Boîte fait partie du prélude de Rust, vous n’aurez donc pas à importer le type, contrairement à d’autres pointeurs intelligents.
La fonction x la variable est un Boîte qui pointe vers la valeur entière 5. Rust alloue la mémoire pour la valeur sur le tas et la désalloue automatiquement lorsque la variable est hors de portée.
2. Le pointeur intelligent Rc
Le Rc (Reference Counted) Le pointeur intelligent permet de créer des valeurs de propriété partagée. Le pointeur Rc Les pointeurs intelligents suivent le nombre de références à une valeur et désallouent la valeur lorsque la dernière référence est hors de portée.
Le Rc Le pointeur intelligent est pratique lorsque vous devez partager la propriété d’une valeur pour qu’elle soit accessible dans plusieurs parties de votre programme.
Pour déclarer un Rc Dans le cas d’un pointeur intelligent, vous importerez le fichier Rc de la bibliothèque standard, déclarer une nouvelle structure Rc pointeur avec le nouveau et clonez la variable pointeur avec la fonction clone variable.
use std::rc::Rc;
fn main() {
// new instance of the RC smart pointer
let x = Rc::new(5);
let y = Rc::clone(&x);
println!("x = {}, y = {}", x, y);
}
Le x est la variable Rc et la variable pointeur y est un clone ayant accès à la valeur en mémoire. Le nombre de références est de deux, et la valeur est désallouée de la mémoire lorsque les variables sont hors de portée.
3. Le pointeur intelligent RefCell
Le RefCell Le pointeur intelligent offre une mutabilité intérieure qui permet aux références immuables et mutables de coexister tant qu’il n’y a qu’une seule référence mutable à un moment donné.
Le RefCell Le pointeur intelligent est pratique lors de la mutation de valeurs appartenant à des références mutables.
La fonction Refcell ne fait pas partie du prélude de Rust, vous devrez donc importer la structure depuis la bibliothèque standard pour utiliser le pointeur intelligent.
use std::cell::RefCell;
fn main(){
// new instance of the Refcell smart pointer
let x = RefCell::new(5);
let y = x.borrow();
let z = x.borrow_mut();
println!("y = {}", *y);
println!("z = {}", *z);
}
La fonction Refcell Le pointeur intelligent contient la valeur, et le y est la référence immuable à la valeur. La variable borrow_mut crée une référence mutable de la valeur.
Le programme est sûr s’il n’y a qu’une seule référence mutable à la fois.
4. Le pointeur intelligent Mutex
Le Mutex Le pointeur intelligent fournit des exclusions mutuelles. Le pointeur intelligent Mutex Le pointeur intelligent est pratique pour synchroniser l’accès aux valeurs entre plusieurs threads dans les programmes concurrents.
L’outil Mutex Le pointeur intelligent permet l’exclusion mutuelle afin de garantir qu’un seul thread peut accéder à la valeur tout en évitant les traces de données.
Vous devez importer le fichier Mutex et créez une nouvelle instance avec la structure nouveau fonction à utiliser Mutex Pointeur intelligent en Rust.
use std::sync::Mutex;
fn main() {
// new instance of the mutex pointer
let counter = Mutex::new(0);
{
let mut num = counter.lock().unwrap();
*num += 1;
}
println!("Result: {}", *counter.lock().unwrap());
}
Le compteur la variable est la nouvelle Mutex instance. L’instance principal acquiert un verrou sur le mutex avec la fonction verrou méthode de la Mutex instance. Le verrou permet de modifier en toute sécurité la valeur du compteur avant de relâcher le verrou et d’imprimer la valeur.
La fonction Mutex garantit qu’un seul thread peut accéder aux ressources partagées (dans ce cas, l’élément compteur ) et de modifier sa valeur à chaque fois. L’exclusion mutuelle garantit que l’accès concurrent aux ressources partagées est sérialisé afin d’éviter les traces de données et autres problèmes de concurrence.
Le modèle de propriété de Rust garantit la sécurité de la mémoire
Les pointeurs intelligents sont l’une des approches de Rust en matière de sécurité mémoire et de flexibilité. Le modèle de propriété de Rust garantit que les programmes utilisent la mémoire en toute sécurité avec le vérificateur d’emprunts au moment de la compilation.
Le vérificateur d’emprunts est une fonctionnalité cruciale du modèle de propriété de Rust qui applique des règles strictes pour l’accessibilité et la modification de la mémoire.
