Rust 스마트 포인터

wangki·2025년 1월 9일
0

Rust

목록 보기
5/54

스마트 포인터란?

c/c++ 에서는 메모리를 할당 후 해제를 직접 해줘야 한다.
스마트 포인터를 사용하면 수동으로 메모리를 해제해 줄 필요가 없다.
즉, 안전하게 메모리를 사용할 수 있도록 도와준다.

스마트 포인터에 대해 쉽게 이해할 수 있도록 식당을 예로 들어보겠습니다.

우리가 식당에서 음식을 먹는다고 상상해 봅시다.
음식메모리라고 생각할 수 있습니다.

1. 셀프 매장에서는 음식을 먹은 후 사용한 식기를 우리가 직접 반납해야 합니다.
즉, 이용자가 직접 메모리를 해제하는 것과 같습니다.

2. 반면에 일반 식당에서는 음식을 먹은 후 그냥 자리를 떠나도 됩니다.
식당 직원들이 알아서 사용한 식기를 치워줍니다.
이는 스마트 포인터가 메모리를 자동으로 해제 해주는 방식과 비슷합니다.

스마트 포인터를 사용하면 프로그래머는 메로리를 사용하는 데 집중할 수 있고, 메모리를 해제하는 번거로운 작업은 스마트 포인터가 대신 처리해줍니다.

이제 Rust에서 스마트 포인터가 어떻게 동작하는지 알아보겠습니다.

1. Box

가장 단순한 스마트 포인터이다. 데이터를 힙(Heap)에 저장하고 소유권을 관리합니다.
단일 소유권을 가집니다.

  • 예시
        let a : Box<i32> = Box::new(10);
    	assert_eq!(*a, 10);

*를 사용하여 역참조한다.

2. Rc

Rc는 여러 소유자를 가능하게 하는 스마트 포인터입니다. 데이터를 힙에 저장하며, 참조 카운터를 통해 소유권을 관리합니다.

불변 참조만 가능합니다.

BoxRc의 메모리 주소로 차이에 대해서 알아보겠습니다.

  • Box의 주소값을 살펴보겠습니다.
    let a : Box<i32> = Box::new(30);
    let b = Box::clone(&a);
    let c = Box::clone(&a);

    println!("a 주소 : {:p}", a);
    println!("b 주소 : {:p}", b);
    println!("c 주소 : {:p}", c);


주소값이 전부 다른걸 볼 수 있습니다.

그렇다면 Rc의 경우를 한번 보겠습니다.

    let a : Rc<i32> = Rc::new(30);
    let b = Rc::clone(&a);
    let c = Rc::clone(&a);

    println!("a 주소 : {:p}", a);
    println!("b 주소 : {:p}", b);
    println!("c 주소 : {:p}", c);
    
    println!("참조 count : {}", Rc::strong_count(&a));

주소값이 동일하게 나온 걸 볼 수 있습니다.
a의 값을 bc가 참조한다고 볼 수 있습니다. 또한 참조 카운터가 3인 걸 볼 수 있습니다.

결론적으로 Box의 경우는 단일 소유권을 가지고 있고, Rc 다중 소유권을 가질 수 있습니다. Rc의 경우 DerefMut를 구현하지 않아 가변 역참조가 불가능하여 값을 수정할 수 없습니다.

3. Arc란?

Arc : Atomic Reference Counted의 약자로, Rust의 스마트 포인터 중 하나이다.
Rc와 비슷하지만, 스레드 간 공유를 지원하도록 설계하였다.

Arc는 멀티 스레드에 대해서 다룰 때 자세히 살펴볼 예정입니다.

0개의 댓글