C.W.K.
Stream
Lesson 05 of 05 · published

Dangling 참조는 없다

~10 min · borrowing, dangling, lifetimes, E0515

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

C 에선 지역 변수로의 포인터를 반환하는 게 전형적 재앙이야: 함수가 반환되면 지역 변수가 파괴되고, 호출자는 해제된 메모리로의 포인터를 든 채 남겨져. Rust 는 이걸 컴파일 불가능 하게 만들어.

거부되는 dangling 참조

함수 안에서 만든 값으로의 참조를 반환하려 들면 borrow checker 가 막아: 그 값은 함수 끝에서 drop 될 테니 참조가 해제된 메모리를 가리키게 돼. Rust 는 그 참조가 빠져나가게 안 둬. 에러가 정확히 뭐가 잘못인지 짚어줘 — 값이 충분히 오래 안 살아.

수정: 참조 말고 소유권을 반환

함수가 값을 만들면 그 값 자체를 반환해야 해 (소유권 이전), 그 참조 말고. 그럼 호출자가 소유하고, 필요한 만큼 살아. 참조는 호출자가 이미 소유한 것에서 빌릴 때만 반환해 — 넘겨받은 파라미터처럼.

참조는 가리키는 대상보다 오래 살 수 없어. 이게 두 번째 빌림 규칙이고, 절대적으로 강제돼. Rust 에서 use-after-free 는 '드문' 게 아니야 — safe 코드에선 구조적으로 불가능하고, 모든 참조에 대해 컴파일 타임에 증명돼.

여기서 lifetime 이 나와

컴파일러는 참조가 데이터보다 오래 안 산다는 걸 어떻게 알아? lifetime 을 추적해 — 각 참조가 얼마나 오래 유효한지. 보통은 조용히 추론해. 근데 함수가 입력에서 파생된 참조를 반환할 땐 가끔 직접 표기해야 해. 그게 다음 트랙 전부야 — 그리고 이제 그게 무슨 문제를 푸는지 정확히 알지.

Code

Rust 가 컴파일 거부하는 dangling 참조·rust
// 이건 컴파일 안 됨:
// fn dangle() -> &String {
//     let s = String::from("oops");
//     &s   // error[E0106]: lifetime 누락 / `s` 가 충분히 오래 안 삶
// }       // s 가 여기서 drop 되니 반환된 참조가 dangle 함

// 수정: 값을 반환, 소유권 이전.
fn no_dangle() -> String {
    let s = String::from("safe");
    s // 소유권이 호출자로 move 아웃 — 필요한 만큼 삶
}

fn main() {
    let s = no_dangle();
    println!("{s}");
}

External links

Exercise

내부에서 만든 String 으로의 참조를 반환하려는 함수를 쓰고 컴파일러 에러를 읽어. 그다음 두 방법으로 고쳐: (1) 소유한 String 을 반환, (2) 참조 파라미터를 받아서 *그것의* 슬라이스를 반환. 2번은 왜 컴파일돼?
Hint
2번은 호출자가 소유한 데이터에서 빌리는데, 그건 함수 호출보다 오래 살아. 참조는 자기보다 오래 사는 걸 가리키는 한 괜찮아.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.