Lifetime issue in Rust

Emir Buğra KÖKSALAN tarafından tarihinde yayınlandı

This issue took me 6 months to figure this out.

Adding explicit lifetime to the biggest function is what will make it clear to the rust compiler that a and b need to stay in scope just as long as return value. so once we add lifetimes to biggest we should get an error down here letting us know that “hey something’s wrong other struct needs to stay in scope just as long as bigger does”.

fn main() {
  let mut s1 = SomeStruct{num: 5};
  let bigger: &SomeStruct;
  {
    let s2 = SomeStruct{num: 6};
    bigger = biggest(&s1, &s2);
  }
  println!("{:?}", bigger);
}

Compiler can’t analyze which reference will be return. If it returns s2’s reference then s2 ownership will be delete and the bigger reference asdasd will be point to null. But with lifetime specifiers compiler can analyze which reference mounted to returned reference lifetime.
In C/C++ you have to handle null pointers yourself.

These are mechanisms which protect us from making mistakes. It is possible that inventing different mechanisms for get rid of null pointer bugs. (It may be possible to invent different mechanisms to recover from null pointer errors.)

This rule has to be in rust because rust has auto drop mechanism. When an ownership reaches to end of the current scope then it will be removed from memory.

// start
#[derive(Debug)]
struct SomeStruct {
    num: i32,
}

fn biggest<'a>(p1: &'a SomeStruct, p2: &'a SomeStruct) -> &'a SomeStruct {
    if p1.num > p2.num {
        p1
    } else {
        p2
    }
}

fn main() {
    let mut s1 = SomeStruct { num: 5 };
    let bigger: &SomeStruct;
    {
        let s2 = SomeStruct { num: 6 }; // Bug1
        bigger = biggest(&s1, &s2);
    }
    println!("{:?}", bigger);
}

// ⏯️ play

Let’s imagine that there is no lifetime specifier control, programmers would definitely make this simple mistake like Bug1. The lifetime specifier control is there to prevent anyone from making this mistake.

They don’t change the lifetimes of the parameters. These are just a guide for the compiler to know which parameter should live and until when.

Sometimes they can be inferred. For example when you have only one parameter and same type return then compiler can infer the lifetime.

Peki derleyici tüm lifetimeların aynı olduğunu farzetse olmaz mıydı? Olurdu ama yazılımcıya esneklik verilmemiş olurdu o zaman. Belki adam üç parametreden sadece sonuncuyu döndermek istiyor, o zaman iki tane lifetime specifier tanımlar, ilk iki parametreye ‘a, üçüncü parametreye de ‘b atar, return typea da ‘b atar var olur biter. Yazılımcıya esneklik kazandırılmış olur böylece.

struct SomeStruct<'a> {
  num: &'a i32,
}

fn main() {
  let s1: SomeStruct;
  {
    let num: 
  }
}

This is telling the compiler that the num has to last at least as long as SomeStruct.

What the hell is “Dangling Reference”?

dangling reference in programming refers to a reference that points to a memory location that has been deallocated or released. In simple terms, it is a pointer or reference that no longer points to a valid object, leading to potential runtime errors or undefined behavior if accessed.

Kategoriler: General

Emir Buğra KÖKSALAN

Java & PHP Developer

0 yorum

Bir yanıt yazın

Avatar placeholder

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Time limit is exhausted. Please reload the CAPTCHA.

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.