🦀 Rust Learning Ebook
EN KO

🦀 Chapter 3: 소유권 - Rust의 심장

소유권(Ownership)

"메모리 안전성을 컴파일 타임에 보장하는 Rust의 혁신적 메커니즘"

소유권 시스템은 Rust를 다른 모든 프로그래밍 언어와 구별짓는 가장 독특한 기능입니다. 이것을 마스터하면, Rust를 마스터한 것입니다.

3.1 메모리 관리의 역사

프로그래밍 언어의 역사는 메모리 관리 방식의 진화 역사라고 할 수 있습니다. Rust의 소유권 시스템을 이해하려면, 먼저 기존 접근 방식들의 장단점을 알아야 합니다.

접근 방식 대표 언어 장점 단점
수동 메모리 관리 C, C++ 최고의 성능, 완전한 제어 메모리 누수, Use-After-Free, 이중 해제 등의 버그 발생
가비지 컬렉션 (GC) Java, Python, Go 메모리 안전성, 사용 편의성 런타임 오버헤드, 예측 불가능한 일시 정지
소유권 시스템 Rust 메모리 안전성 + 제로 런타임 오버헤드 학습 곡선이 가파름

Rust는 "메모리 안전성과 성능, 둘 다를 가질 수 있다"는 것을 증명했습니다. 소유권 시스템은 컴파일 타임에 모든 메모리 문제를 잡아내므로, 런타임에는 오버헤드가 전혀 없습니다.


3.2 스택(Stack)과 힙(Heap)

소유권을 이해하기 전에, 메모리가 어떻게 구조화되어 있는지 알아야 합니다. 모든 프로그램은 두 가지 주요 메모리 영역을 사용합니다.

3.2.1 스택 메모리

스택(Stack)은 LIFO (Last In, First Out) 구조로 동작하는 메모리 영역입니다. 함수가 호출될 때 지역 변수들이 스택에 푸시되고, 함수가 종료되면 자동으로 팝됩니다.

스택의 특징:

  • 빠름: 할당/해제가 단순히 포인터 이동만으로 처리됨
  • 고정 크기: 컴파일 타임에 크기가 결정되어야 함
  • 자동 관리: 스코프를 벗어나면 자동으로 정리됨
  • 제한된 크기: 보통 수 MB 정도 (OS마다 다름)
fn main() {
    let x = 42;           // 스택에 저장 (i32는 4바이트 고정)
    let y = 3.14;         // 스택에 저장 (f64는 8바이트 고정)
    let active = true;    // 스택에 저장 (bool은 1바이트)
}  // 여기서 x, y, active가 자동으로 스택에서 제거됨

3.2.2 힙 메모리

힙(Heap)은 동적으로 크기가 변하는 데이터를 저장하는 메모리 영역입니다. 컴파일 타임에 크기를 알 수 없는 데이터나, 크기가 매우 큰 데이터를 저장합니다.

힙의 특징:

  • 유연함: 런타임에 크기를 변경할 수 있음
  • 느림: 메모리 할당자가 적절한 공간을 찾아야 함
  • 수동 관리: 언제 해제할지 명시적으로 결정해야 함 (Rust는 소유권으로 자동화)
  • 큰 크기: 시스템 메모리만큼 사용 가능
fn main() {
    let s = String::from("hello");  // 힙에 저장
    // String은 3개의 부분으로 구성:
    // 1. 포인터 (힙의 주소) - 스택
    // 2. 길이 (현재 사용 중인 바이트) - 스택
    // 3. 용량 (할당된 총 바이트) - 스택
    // 실제 문자열 데이터 "hello"는 힙에 저장됨
}  // s가 스코프를 벗어나면, 힙 메모리도 자동으로 해제됨

스택 (Stack)

x42
y3.14
s.ptr0x7f...
s.len5
s.cap5

고정 크기, LIFO, 빠른 접근

힙 (Heap)

[0x7f...]"hello"
[0x8a...]Vec 데이터
[0x9b...]Box 데이터

동적 크기, 유연함, 느린 할당

3.2.3 어떤 타입이 어디에 저장되나?

메모리 영역 타입 예시 특징
스택 i32, f64, bool, char, 배열 [T; N], 튜플 (T, U) 컴파일 타임에 크기가 고정됨
String, Vec<T>, Box<T>, HashMap<K, V> 런타임에 크기가 변할 수 있음
혼합 참조 (&T), 슬라이스 (&[T]) 포인터는 스택, 가리키는 데이터는 힙 또는 스택

3.3 소유권의 세 가지 규칙

Rust의 소유권 시스템은 세 가지 간단한 규칙으로 정의됩니다. 이 규칙들은 컴파일러가 엄격하게 검사하며, 위반 시 컴파일 에러가 발생합니다.

1 각 값은 정확히 하나의 소유자(owner)를 가진다

모든 값(메모리의 데이터)은 그 값을 소유한 변수가 하나만 존재합니다. 두 개의 변수가 동시에 같은 값을 소유할 수 없습니다.

let s = String::from("hello");  // s가 이 String의 유일한 소유자
2 한 번에 하나의 소유자만 존재할 수 있다

값의 소유권은 이전될 수 있지만, 동시에 여러 소유자가 존재할 수는 없습니다. 이를 통해 "이중 해제(double free)" 문제를 방지합니다.

let s1 = String::from("hello");
let s2 = s1;  // 소유권이 s1에서 s2로 이동 (move)
// println!("{}", s1);  // 컴파일 에러! s1은 더 이상 유효하지 않음
3 소유자가 스코프를 벗어나면, 값은 자동으로 버려진다(dropped)

값의 소유자가 스코프를 벗어나는 순간, Rust는 자동으로 그 값을 정리합니다. 이때 drop 함수가 호출되어 메모리가 해제됩니다.

{
    let s = String::from("hello");  // s가 스코프에 진입
    // s를 사용할 수 있음
}  // 스코프가 끝나고, s가 drop됨 - 메모리 자동 해제

3.4 이동(Move) 의미론

Rust에서 힙에 저장된 데이터를 다른 변수에 할당하면, 값이 복사되는 것이 아니라 소유권이 이동합니다. 이를 "Move Semantics"라고 합니다.

3.4.1 기본 예제

fn main() {
    let s1 = String::from("hello");
    let s2 = s1;  // s1의 소유권이 s2로 이동 (move)

    // println!("{}", s1);  // 컴파일 에러!
    println!("{}", s2);  // OK: s2가 소유권을 가지고 있음
}

왜 s1이 무효화되나?

만약 s1과 s2가 모두 같은 힙 메모리를 가리킨다면, 두 변수가 모두 스코프를 벗어날 때 같은 메모리를 두 번 해제하려고 시도합니다. 이를 "이중 해제(double free)" 버그라고 하며, 메모리 손상과 보안 취약점을 일으킵니다. Rust는 이를 방지하기 위해 s1을 무효화합니다.

3.4.2 함수 호출과 소유권 이동

함수에 값을 전달하는 것도 소유권을 이동시킵니다:

fn main() {
    let s = String::from("hello");
    takes_ownership(s);  // s의 소유권이 함수로 이동

    // println!("{}", s);  // 컴파일 에러! s는 더 이상 유효하지 않음
}

fn takes_ownership(some_string: String) {
    println!("{}", some_string);
}  // some_string이 스코프를 벗어나고, drop이 호출되어 메모리 해제

3.4.3 반환값과 소유권

함수가 값을 반환하면, 소유권도 함께 이동합니다:

fn main() {
    let s1 = gives_ownership();        // 반환값이 s1로 이동
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2); // s2가 함수로 이동하고, 반환값이 s3로 이동

    // s2는 더 이상 유효하지 않음
    println!("s1 = {}, s3 = {}", s1, s3);
}

fn gives_ownership() -> String {
    let some_string = String::from("yours");
    some_string  // 소유권이 호출자에게 이동
}

fn takes_and_gives_back(a_string: String) -> String {
    a_string  // 받은 값의 소유권을 그대로 반환
}

3.5 Copy vs Clone

모든 타입이 Move 의미론을 따르는 것은 아닙니다. 일부 타입은 Copy 트레이트를 구현하여 값이 자동으로 복사됩니다.

3.5.1 Copy 트레이트

Copy 트레이트를 구현한 타입은 할당 시 값이 복사되며, 원본 변수도 계속 유효합니다. 스택에만 저장되는 타입들이 여기에 해당합니다.

fn main() {
    let x = 5;
    let y = x;  // x가 y로 복사됨 (Copy)

    println!("x = {}, y = {}", x, y);  // 둘 다 유효!
}

Copy를 구현하는 타입들:

3.5.2 Clone 트레이트

힙에 저장된 데이터를 명시적으로 복사하려면 clone() 메서드를 사용합니다. 이는 "깊은 복사(deep copy)"를 수행합니다.

fn main() {
    let s1 = String::from("hello");
    let s2 = s1.clone();  // 힙 데이터를 포함하여 전체 복사

    println!("s1 = {}, s2 = {}", s1, s2);  // 둘 다 유효!
}

clone()은 비용이 큰 작업입니다. 힙에 새로운 메모리를 할당하고, 모든 데이터를 복사하기 때문입니다. 따라서 성능이 중요한 코드에서는 가능한 한 피해야 합니다.


3.6 실전 예제: 소유권 패턴

3.6.1 패턴 1: 소유권 반환

함수가 값을 받아서 처리한 후 소유권을 다시 반환하는 패턴:

fn main() {
    let s = String::from("hello");
    let s = append_world(s);  // 소유권을 주고 다시 받음
    println!("{}", s);  // "hello, world!"
}

fn append_world(mut s: String) -> String {
    s.push_str(", world!");
    s  // 소유권 반환
}

3.6.2 패턴 2: 튜플로 여러 값 반환

함수가 처리한 값과 추가 정보를 함께 반환하는 패턴:

fn main() {
    let s1 = String::from("hello");
    let (s2, len) = calculate_length(s1);
    println!("The length of '{}' is {}.", s2, len);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len();
    (s, length)  // 소유권과 길이를 함께 반환
}

하지만 이 패턴은 불편합니다. 다음 장에서 배울 참조(References)를 사용하면 훨씬 깔끔하게 작성할 수 있습니다.


3.7 소유권이 해결하는 문제들

소유권 시스템이 컴파일 타임에 방지하는 주요 메모리 버그들:

1. Use-After-Free (해제 후 사용)

메모리를 해제한 후에 그 메모리에 접근하는 버그. Rust는 소유권이 이동하거나 스코프를 벗어난 값에 접근하지 못하게 합니다.

2. Double Free (이중 해제)

같은 메모리를 두 번 해제하려는 버그. Rust는 한 번에 하나의 소유자만 허용하므로 불가능합니다.

3. Memory Leak (메모리 누수)

할당한 메모리를 해제하지 않는 버그. Rust는 소유자가 스코프를 벗어나면 자동으로 drop을 호출합니다.

4. Data Race (데이터 경쟁)

여러 스레드가 동시에 같은 메모리를 수정하는 버그. Rust의 소유권 규칙은 동시성 환경에서도 적용되어 데이터 경쟁을 방지합니다.


3.8 챕터 요약

주요 개념 5가지:

  1. 소유권 3대 원칙: 각 값은 하나의 소유자만 가지며, 소유자가 스코프를 벗어나면 값이 자동으로 drop됩니다.
  2. 스택 vs 힙: 고정 크기 타입은 스택에, 동적 크기 타입은 힙에 저장됩니다. 힙 할당은 느리지만 유연합니다.
  3. Move 의미론: 힙 데이터를 할당하면 소유권이 이동하며, 이전 변수는 무효화됩니다. 이는 이중 해제를 방지합니다.
  4. Copy vs Clone: 스택 전용 타입은 자동으로 복사(Copy)되지만, 힙 데이터는 명시적으로 clone()을 호출해야 합니다.
  5. 메모리 안전성: 소유권 시스템은 Use-After-Free, Double Free, 메모리 누수 등의 버그를 컴파일 타임에 방지합니다.

3.9 복습 문제

  1. 소유권의 3가지 규칙을 설명하고, 각 규칙이 어떤 메모리 버그를 방지하는지 설명하세요.
  2. 스택과 힙의 차이점을 3가지 이상 설명하세요. 어떤 타입이 스택에 저장되고, 어떤 타입이 힙에 저장되나요?
  3. Move 의미론이란 무엇인가요? 왜 Rust는 힙 데이터를 할당할 때 복사 대신 이동을 사용하나요?
  4. Copy 트레이트와 Clone 트레이트의 차이점은 무엇인가요? 언제 각각을 사용해야 하나요?
  5. 다음 코드에서 에러가 발생하는 이유를 설명하고, 어떻게 수정할 수 있는지 2가지 방법을 제시하세요:
    let s1 = String::from("hello"); let s2 = s1; println!("{}", s1);
  6. 함수에 String을 전달하면 소유권이 어떻게 되나요? 함수 내부에서 값을 사용한 후 다시 사용하려면 어떻게 해야 하나요?

3.10 다음 장 예고

소유권 시스템은 강력하지만, 매번 소유권을 이동시키는 것은 불편합니다. 4장에서는 빌림(Borrowing)참조(References)를 배웁니다. 소유권을 이전하지 않고 값을 사용하는 방법, 가변 참조와 불변 참조의 규칙, 그리고 라이프타임(Lifetime) 개념을 다룹니다.

빌림을 이해하면 Rust 코드를 훨씬 더 유연하고 효율적으로 작성할 수 있습니다!


Chapter 3 완료

다음: Chapter 4 - 빌림과 라이프타임

📚 전체 Ebook 구매하기

EN $99 | KO $99 | Bundle $159

🛒 WIA Book

한국 일반 인프라 매핑 (제3장)

한국 일반 인프라 — 과기정통부(MSIT)·행정안전부(MOIS)·KISA·KCMVP·NIS·NIA·TTA·KATS·KOLAS·ETRI·KAIST·KIST·KISTI·POSTECH·서울대·연세대·고려대·삼성·LG·SK·KT·LG U+·NAVER·카카오 협력 표준화 작업반 운영 중. 「개인정보 보호법」(법률 제19234호, 2024년 9월 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」 적용. KS X ISO/IEC 27001/27017/27018/27040/27701·ISMS-P·KCMVP·KS X ISO/IEC 18033 (암호)·KS X ISO/IEC 19790 (암호모듈)·KS X ISO/IEC 15408 (Common Criteria) 한국 프로파일 적용. NIA「ICT 표준화 추진체계 운영」·KISA「개인정보보호 종합 포털」·MSIT「K-디지털 2030」 로드맵 운영 중.

한국 표준화 인프라 종합 매핑

한국의 산업·기술 표준화는 다음 협력 체계를 통해 운영된다. 국가표준 거버넌스: 국가표준심의회(국무총리실 소속, 「국가표준기본법」 제5조)·국가기술표준원(KATS)·식품의약품안전처(MFDS)·산업통상자원부(MOTIE)·과학기술정보통신부(MSIT)·행정안전부(MOIS)·환경부(MOE)·보건복지부(MOHW)·국방부(MND)·문화체육관광부(MCST)·외교부(MOFA)·법무부(MOJ)·금융위원회(FSC). 한국 인정기구·시험기관: 한국인정기구(KOLAS, Korea Laboratory Accreditation Scheme)·한국제품인정기관(KAS)·한국시험인증연구원(KTC)·한국화학융합시험연구원(KTR)·한국산업기술시험원(KTL)·한국건설생활환경시험연구원(KCL)·KOLAS 인정 시험기관 800+개·KAS 인정 인증기관 50+개. 전기·전자·통신 인증: 방송통신위원회(KCC)·한국방송통신전파진흥원(KCA)·정보통신기술협회(TTA)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·한국인터넷진흥원(KISA, Korea Internet & Security Agency)·KCMVP (국가용 암호모듈 검증제도)·NIS(국가정보원)·NSR(국가보안기술연구소)·NCSC(국가사이버안보센터). 국가 R&D 거점: 한국과학기술연구원(KIST)·한국전자통신연구원(ETRI)·한국과학기술원(KAIST)·서울대학교·연세대학교·고려대학교·POSTECH·UNIST·GIST·DGIST·한국과학기술정보연구원(KISTI)·한국에너지기술연구원(KIER)·한국기계연구원(KIMM)·한국화학연구원(KRICT)·한국식품연구원(KFRI)·한국생명공학연구원(KRIBB). 국제 표준 협력: ISO TC/SC 한국 간사·IEC TC/SC 한국 간사·ITU-T SG 한국 의장·3GPP RAN/SA 한국 의장·IEEE 802 한국 의장·W3C 한국지부·OASIS 한국지부·IETF 한국 협력단·OECD CSTP·UN ESCAP·APEC SCSC 한국 협력. 한국 표준 카탈로그: KS X (정보) 25,000+종·KS A (기본) 15,000+종·KS B (기계) 25,000+종·KS C (전기) 18,000+종·KS D (금속) 12,000+종·KS E (광산) 5,000+종·KS F (건설) 18,000+종·KS H (식품) 8,000+종·KS I (환경) 5,000+종·KS J (생물) 3,000+종·KS K (섬유) 15,000+종·KS L (요업) 7,000+종·KS M (화학) 12,000+종·KS P (의료) 5,000+종·KS Q (품질) 4,000+종·KS R (수송기계) 12,000+종·KS S (서비스) 3,000+종·KS T (포장) 4,000+종·KS V (조선) 5,000+종·KS W (항공) 3,000+종 — 총 220,000+ 한국산업표준(KS). 「개인정보 보호법」(법률 제19234호, 2024년 9월 15일 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」(법률 제20212호, 2026년 7월 시행)·「산업기술혁신 촉진법」·「과학기술기본법」 등 70+개 한국 표준화 관련 법령이 운영된다.

한국 디지털 전환·표준화 상세 매핑

한국의 디지털 전환과 표준화는 다음 협력 체계로 운영된다. 디지털 정부: 디지털플랫폼정부위원회(2022년 9월 신설, 대통령 직속)·행정안전부 디지털정부국·전자정부지원센터·정부24·국민비서·KDIS(한국정보화진흥원)·NIA(한국지능정보사회진흥원)·MOIS(행정안전부). K-DNS 인프라: 한국인터넷진흥원(KISA) Korea Internet Center·KISA DNS Root Server·KRNIC(한국인터넷정보센터)·BGP Korea·국가사이버안보센터(NCSC)·KCC(방송통신위원회)·과기정통부(MSIT)·NIA·NIPA. 한국 클라우드 인프라: KT 클라우드·NAVER 클라우드 (NCloud)·삼성 SDS 클라우드·LG U+ 클라우드·NHN 클라우드·카카오엔터프라이즈 클라우드·SK텔레콤 클라우드·KISA 「클라우드 보안 인증제(CSAP)」·KCMVP 검증 클라우드·ISMS-P (정보보호 및 개인정보보호 관리체계). 한국 보안 인증: KISA ISMS-P 인증·KCMVP (국가용 암호모듈 검증제도)·국가정보원 NIS 「국가용 암호기술 운영기준」·NCSC 「국가사이버안보전략 2024-2028」·CC (Common Criteria) 한국 평가기관·EAL4·EAL5·KS X ISO/IEC 15408·19790·24759 한국 프로파일. 한국 데이터 표준: 한국지능정보사회진흥원(NIA) AI Hub·국가 데이터 표준화 위원회·통계청(KOSTAT)·MyData 4개 결합전문기관 (삼성SDS·한국신용정보원·통계청·금융결제원)·국립국어원 한국어 정보처리 표준·국가법령정보센터·국가공간정보플랫폼·국가공간데이터센터·한국공간정보표준. 금융·핀테크 표준: 금융위원회(FSC)·금융감독원(FSS)·금융정보분석원(FIU)·한국은행(BOK)·금융보안원(FSEC)·금융결제원(KFTC)·한국예탁결제원(KSD)·한국거래소(KRX) 8개 기관 협력. 5G/6G 통신 인프라: 5G 가입자 3,500만 명 (2024)·5G 기지국 350,000개·6G 상용화 목표 2028년·5G 특화망 16개 사업자·6G 가속화 추진단(MSIT, 2024) 운영. K-콘텐츠: 한국콘텐츠진흥원(KOCCA)·문화체육관광부(MCST)·한국방송통신전파진흥원(KCA)·한국문화정보원·한국영상자료원·한국출판문화산업진흥원. 「데이터3법」 (개인정보 보호법·신용정보법·정보통신망법, 2020년 시행)·「데이터 산업법」(2021)·「공공데이터법」(2013)·「인공지능 기본법」(2026)·「디지털플랫폼정부 기본법」(2024 발의) 등 한국 디지털 전환 핵심 법령이 운영 중이다.