포슀트

🌚 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ - Pointer and Refernece Types

2023-12-15. 12:20
πŸŒ‘ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ - Pointer and Reference Types κΈ€ κ³„μŠΉ


πŸ’« 포인터 Pointer


@ U 기말고사 좜제 : C 포인터λ₯Ό μ‚¬μš©ν•˜λŠ”λ° μžˆμ–΄μ„œ λ°œμƒν•  수 μžˆλŠ” 문제인 Dangling Pointer와 Memory Leaking에 λŒ€ν•˜μ—¬ μ„€λͺ…ν•˜μ‹œμ˜€. 이에 λŒ€ν•œ 해결책도 같이 μ„€λͺ…ν•˜μ‹œμ˜€.

  • 포인터 λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό κ°€μ§€λŠ” νƒ€μž…μ΄λ‹€.
  • νŠΉμˆ˜κ°’ NIL/NULL μ£Όμ†Œλ₯Ό 가지면, λ©”λͺ¨λ¦¬ μ°Έμ‘°λ₯Ό ν•  수 μ—†μŒμ„ μ˜λ―Έν•œλ‹€.

  • 포인터 μ„€κ³„μ˜ μš©λ„
    • κ°„μ ‘ μ£Όμ†Œμ§€μ • 방식을 μ§€μ›ν•˜κΈ° μœ„ν•΄
      • Scope룰에 μ˜ν•΄ 직접 접근이 μ•ˆλ˜λŠ” λŒ€μƒμ— κ°„μ ‘μ μœΌλ‘œ μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ¨
    • 동적 기얡곡간(νž™ heap)을 κ΄€λ¦¬ν•˜λŠ” 방식을 μ œκ³΅ν•˜κΈ° μœ„ν•΄
  • νž™-동적 λ³€μˆ˜
    • νž™κ³΅κ°„μ— λ™μ μœΌλ‘œ ν• λ‹Ήλ˜λŠ” λ³€μˆ˜
    • μ‹λ³„μž(이름)κ°€ μ—†μŒ -> 무λͺ… λ³€μˆ˜ (νž™μ΄ Nameless 둜 λΆˆλ¦¬κΈ°λ„ 함)
      • λ”°λΌμ„œ 포인터λ₯Ό μ΄μš©ν•˜μ—¬ κ°„μ ‘μ μœΌλ‘œ 접근이 κ°€λŠ₯
  • ν¬μΈν„°λŠ” 동적 자료ꡬ쑰의 μž‘μ„±λ ₯을 ν–₯μƒμ‹œν‚΄
    • Fortran 77μ—μ„œλŠ” 동적 κΈ°μ–΅κ³΅κ°„μ΄Β μ—†μŒ 그리고 이진 νŠΈλ¦¬μ™€ 같은 동적 ꡬ쑰λ₯ΌΒ λ°°μ—΄κ³Ό κ°™μ€Β μ΄μš©ν•˜μ—¬ κ΅¬ν˜„ν•΄μ•Ό ν•˜λ―€λ‘œΒ μž‘μ„±λ ₯이 떨어짐
  • 섀계 고렀 사항
    • 포인터 λ³€μˆ˜μ˜ μ˜μ—­κ³Ό 쑴속기간은 무엇인가?
    • νž™-동적 λ³€μˆ˜(포인터가 μ°Έμ‘°ν•˜λŠ” κ°’)의 쑴속기간은 무엇인가?
    • ν¬μΈν„°λŠ”Β κ°€λ¦¬ν‚¬ 수 μžˆλŠ” κ°’μ—λŠ” μ œμ•½μ΄ μžˆλŠ”κ°€?
    • 포인터가 동적 기얡곡간 관리, κ°„μ ‘ μ£Όμ†Œμ§€μ • λ˜λŠ” 두 가지 λͺ¨λ‘λ₯Ό μœ„ν•΄ μ‚¬μš©λ˜λŠ”κ°€?
    • μ–Έμ–΄κ°€ 포인터 νƒ€μž…, μ°Έμ‘° νƒ€μž…, λ˜λŠ” 두 가지 λͺ¨λ‘λ₯Ό μ§€μ›ν•˜λŠ”κ°€?
  • C/C++의 포인터
    • μ–΄μ…ˆλΈ”λ¦¬μ—μ„œ μ£Όμ†Œλ₯Ό μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ C/C++μ—μ„œ μ£Όμ†Œλ₯Ό μ‚¬μš© κ°€λŠ₯
      • μœ μ—°μ„±μ„ μ œκ³΅ν•˜λ‚˜ ν—ˆμƒ 포인터(dangling pointer)λ‚˜ λ©”λͺ¨λ¦¬ λˆ„μˆ˜(memory leaking)κ³Ό 같은 λ¬Έμ œμ— μ–΄λ–€ 해결책도 μ œμ‹œν•˜μ§€ μ•ŠμŒ -> 맀우 μ‘°μ‹¬ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό 함
    • 포인터 μ—°μ‚°
      • *: μ—­μ°Έμ‘° μ—°μ‚°
      • &: λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό μƒμ„±ν•˜κΈ° μœ„ν•œ μ—°μ‚°
      • +: ν¬μΈν„°μ˜ μ£Όμ†Œ λ§μ…ˆ μ—°μ‚°
      • λ°°μ—΄μ˜ μš”μ†Œ 접근을 μœ„ν•΄ μ‚¬μš©
    • 포인터 μ •μ˜
      • β€œνƒ€μž… *β€œμ„ μ΄μš©ν•˜μ—¬ 포인터λ₯Ό μ •μ˜ 함
    • λ³€μˆ˜μ˜ μ£Όμ†Œ 계산 및 μ—­μ°Έμ‘°
      • λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό 계산할 경우 & μ—°μ‚°μžλ₯Ό μ‚¬μš©
      • μ£Όμ†Œκ°’μ— λŒ€ν•œ μ—­μ°Έμ‘°λ₯Ό μˆ˜ν–‰ν•  경우 * μ—°μ‚°μžλ₯Ό μ‚¬μš©
      • 예) pointer_basic.c
    • Scope이 λ‹€λ₯Έ λ³€μˆ˜μ— λŒ€ν•œ κ°„μ ‘ μ°Έμ‘°
      • Scopeλ£°μ—Β μ˜ν•΄ 직접 접근이 μ•ˆλ˜λŠ” λŒ€μƒμ— κ°„μ ‘μ μœΌλ‘œΒ μ ‘κ·Ό ν•˜κΈ° μœ„ν•΄ μ‚¬μš© 됨
      • 예) pointer_indirect.c
    • λ°°μ—΄κ³Ό 포인터
      • C/C++μ—μ„œ λ°°μ—΄λͺ…은 μ£Όμ†Œκ°’, ν¬μΈν„°λŠ” λ³€μˆ˜
      • C/C++μ—μ„œ λ°°μ—΄ 자체λ₯Ό ν•¨μˆ˜μ˜ 인자둜 λ„˜κΈΈ 수 μ—†μœΌλ©° 포인터λ₯Ό μ‚¬μš©ν•΄μ•Ό 함
      • μ£Όμ†Œκ°’ 연산을 톡해 ν•­λͺ©λ“€μ„ μ ‘κ·Όν•˜λŠ” 것이 κ°€λŠ₯
        • λ°°μ—΄μ˜ μš”μ†Œ μ ‘κ·Ό a[1]은 μ‹€μ œλ‘œ C μ»΄νŒŒμΌλŸ¬μ—μ˜ν•΄ *(a + 1)둜 처리
      • C Programming Language의 β€œ5.3절 Pointers and Arrays” 참쑰
      • 예) pointer_array_1.c, pointer_array_2.c, pointer_array_cpp.cpp
    • ꡬ쑰체와 포인터
      • ꡬ쑰체의 멀버λ₯Ό μ ‘κ·Όν•  경우 . μ—°μ‚°μžλ₯Ό μ‚¬μš©
        • ꡬ쑰체λ₯Ό ν¬μΈν„°λ‘œ 지정할 경우 (*ptr).member둜 μ‚¬μš©ν•΄μ•Όν•˜λ©° μ΄λŠ” ptr->member둜 μ‚¬μš© κ°€λŠ₯Β Β 
      • 예) pointer_struct.c, pointer_struct_cpp.cpp
  • 포인터가 μœ λ°œν•  수 μžˆλŠ” 문제
    • Dangling pointer (Stray pointer, ν—ˆμƒ 포인터)
      • 이미 회수된 νž™-동적 λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό 가지고 μžˆλŠ” 포인터
      • 문제점
        • 포인터가 κ°€λ¦¬ν‚€λŠ” λ©”λͺ¨λ¦¬κ°€ 회수된 ν›„ λ‹€μ‹œ ν• λ‹Ή 된 경우 이전 포인터λ₯Ό μ΄μš©ν•œ κ°’μ˜ 변경은 문제λ₯Ό λ°œμƒμ‹œν‚¬ 수 있음
        • 예) dangling_pointer.c
      • ν•΄κ²°μ±…
        • 포인터가 κ°€λ¦¬ν‚€λŠ” λ©”λͺ¨λ¦¬κ°€ 회수된 경우, 포인터λ₯Ό NULL둜 μ„€μ •ν•œλ‹€.
    • Memory leaking (λ©”λͺ¨λ¦¬ λˆ„μˆ˜)
      • 더 이상 μ ‘κ·Όν•  수 μ—†λŠ” νž™-동적 λ³€μˆ˜(μ“°λ ˆκΈ°)κ°€ λ°œμƒν•˜λŠ” ν˜„μƒ
        • μ“°λ ˆκΈ°(Garbage): λ³€μˆ˜λ“€μ΄ μ›λž˜μ˜ λͺ©μ μ—μ— μœ μš©ν•˜μ§€ μ•Šκ³ , ν”„λ‘œκ·Έλž¨μ—μ„œ μƒˆλ‘œμš΄ μš©λ„λ‘œ λ‹€μ‹œ ν™œμš©ν•  수 μ—†λŠ” λ©”λͺ¨λ¦¬
      • 예) memory_leaking.c
      • ν•΄κ²°μ±…
        • νž™-동적 λ³€μˆ˜λ₯Ό λ‹€ μ‚¬μš©ν•˜κ³  λ‚˜λ©΄ λ°˜λ“œμ‹œ λ°˜λ‚©μ„ ν•˜λΌ.
          • Cμ—μ„œλŠ” freeν•¨μˆ˜ C++μ—μ„œλŠ” delete μ—°μ‚°
  • μ°Έμ‘° νƒ€μž…
    • λ©”λͺ¨λ¦¬μ˜ κ°μ²΄λ‚˜ 값을 μ°Έμ‘°ν•˜λŠ” μš©λ„
      • ν¬μΈν„°λŠ” λ©”λͺ¨λ¦¬μ˜ μ£Όμ†Œλ₯Ό μ°Έμ‘°
    • ν¬μΈν„°λŠ” μ£Όμ†Œμ— λŒ€ν•œ μ‚°μˆ  연산이 κ°€λŠ₯ν•˜λ‚˜, μ°Έμ‘°λŠ” μ£Όμ†Œμ— λŒ€ν•œ μ‚°μˆ  연산이 ν—ˆμš©λ˜μ§€ μ•ŠμŒ
    • C++μ—μ„œμ˜ μ°Έμ‘° νƒ€μž…
      • λ¬΅μ‹œμ μœΌλ‘œ μ—­μ°Έμ‘°λ˜λŠ” μƒμˆ˜ ν¬μΈν„°λ‘œ λ³€μˆ˜μ˜ μ •μ˜μ˜μ—μ„œ &λ₯Ό μ‚¬μš©
        • C++의 μ°Έμ‘° νƒ€μž…μ€ ν•œλ²ˆ μ΄ˆκΈ°ν™”λ˜λ©΄ λ‹€λ₯Έ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ μ„€μ •ν•  수 μ—†μŒ
        • 예) reference_1.cpp
      • μ°Έμ‘° νƒ€μž…μ„ μ΄μš©ν•˜μ—¬ ν˜•μ‹ λ§€κ°œλ³€μˆ˜μ˜ 전달에 ν™œμš© (μ»΄νŒŒμΌλŸ¬κ°€ μ£Όμ†Œ 전달)
        • ν¬μΈν„°λŠ” 가독성이 떨어지고 μ•ˆμ „ν•˜μ§€ μ•Šμ€ 연산을 μœ λ°œν•  수 있음
        • ν•˜μ§€λ§Œ μ°Έμ‘° νƒ€μž… λ˜ν•œ 원본 값을 λ³€ν™”μ‹œν‚€λŠ” λΆ€μž‘μš©μ„ μœ λ°œν•  수 있음
        • 예) reference_2.cpp
      • Javaμ—μ„œμ˜ μ°Έμ‘° νƒ€μž…
        • μ•ˆμ •μ„± ν–₯상을 μœ„ν•΄ C/C++ μœ ν˜•μ˜ 포인터λ₯Ό 제거
        • Javaμ—μ„œλŠ”Β κ°μ²΄λ₯Ό μ°Έμ‘°ν•  수 μžˆλ„λ‘ μ‚¬μš©ν•˜λ©° λ³€μˆ˜ μž„(μƒμˆ˜κ°€ μ•„λ‹˜)
        • Javaμ—μ„œ 객체듀은 Managed-Heap에 ν• λ‹Ήλ˜λ©° μ°Έμ‘°λ₯Ό 톡해 접근됨
          • μ–΄λ–€ μ°Έμ‘°λ„Β λ˜μ§€ μ•ŠλŠ” κ°μ²΄λŠ” GC(Garbage Collector)에 μ˜ν•΄ 회수 -> λ©”λͺ¨λ¦¬ λˆ„μˆ˜κ°€ μ—†μŒ
        • 예) StudentExam.java
      • C#
        • 포인터와 Java μŠ€νƒ€μΌμ˜ μ°Έμ‘°λ₯Ό λͺ¨λ‘ 포함, ν•˜μ§€λ§Œ 포인터 μ‚¬μš©μ€ ꢌμž₯치 μ•ŠμŒ
          • C/C++과의 연동을 μœ„ν•˜μ—¬ 포함됨, 포인터 μ‚¬μš©μ‹œ unsafeλΌλŠ” μ§€μ •μž ν•„μš”
          • 참쑰된 κ°μ²΄λŠ” λ¬΅μ‹œμ μœΌλ‘œ νšŒμˆ˜λ˜λ‚˜ 포인터λ₯Ό μ΄μš©ν•˜μ—¬ 참쑰된 κ°μ²΄λŠ” λͺ…μ‹œμ  νšŒμˆ˜κ°€ ν•„μš”
      • Smalltalk, Python, Ruby, Lua
        • λͺ¨λ“  λ³€μˆ˜λŠ” μ°Έμ‘° νƒ€μž…μ΄λ©° λͺ¨λ“  λŒ€μƒμ€ κ°μ²΄μž„
        • 예) student_exam.py
  • 평가
    • ν¬μΈν„°λŠ” ν—ˆμƒ 포인터(Dangling Pointer)와 λ©”λͺ¨λ¦¬ λˆ„μˆ˜(Memory Leaking)κ³Ό 같은 문제 내포
    • 포인터 λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬μ˜ μ°Έμ‘° λ²”μœ„λ₯Ό ν™•λŒ€ν•˜λŠ” κ²½ν–₯이 있음
      • β€œκ³ κΈ‰μ–Έμ–΄μ—μ„œ ν¬μΈν„°μ˜ λ„μž…μ€ κ²°μ½” νšŒλ³΅ν•  수 μ—†λŠ” ν•œ 걸음의 ν›„ν‡΄μ˜€λ‹€β€ - Hoare
    • ν¬μΈν„°λŠ” λ””λ°”μ΄μŠ€ λ“œλΌμ΄λ²„(μž₯치 κ΄€λ¦¬μž)와 같은 μ‹œμŠ€ν…œ ν”„λ‘œκ·Έλž¨Β  μž‘μ„±μ—λŠ” ν•„μˆ˜μ μΈ μš”μ†Œ
    • Java, C#, Pythonλ“±μ˜ μ°Έμ‘° λ³€μˆ˜λŠ” μ•ˆμ •μ„±κ³Ό μœ μ—°μ„±μ„ 제곡
      • κ²°κ΅­ 포인터와 μ°Έμ‘° λ³€μˆ˜λŠ” μ„±λŠ₯(ν˜Ήμ€ 자유)와 μ•ˆμ „μ„±μ˜ Trade-off

πŸ’« 과제 1


κ΅μž¬μ™€ 기타 μžλ£Œλ“€μ„ μ°Έκ³ ν•˜μ—¬, Pointer와 Reference Type듀을 μ •λ¦¬ν•˜κ³  μ΄ν•΄ν•˜λΌ.
ꡐ재 β€˜Concepts of Programming Languages’, 6.11 Pointer와 Reference Type

πŸ’« Pointer

λ©”λͺ¨λ¦¬ μ£Όμ†Œ, 특수 κ°’, nil (null) 값을 κ°€μ§ˆ 수 μžˆλŠ” λ³€μˆ˜λ‹€.
nil은 μœ νš¨ν•œ μ£Όμ†Œκ°€ μ•„λ‹ˆλ©°, ν˜„μž¬ ν•΄λ‹Ή 포인터가 λ©”λͺ¨λ¦¬ 셀을 μ°Έμ‘°ν•˜λŠ” 데에 μ“Έ 수 μ—†μŒμ„ λ‚˜νƒ€λ‚΄λŠ” 데 쓰인닀.

ν¬μΈν„°λŠ” 두 가지 μš©λ„λ‘œ μ„€κ³„λ˜μ—ˆλ‹€.

  1. μ–΄μ…ˆλΈ”λ¦¬μ—μ„œ 주둜 μ‚¬μš©λ˜λŠ” κ°„μ ‘ μ£Όμ†Œ 지정
  2. 동적 μ €μž₯곡간 관리

포인터λ₯Ό μ‚¬μš©ν•˜μ—¬, νž™ - Heap에 λ™μ μœΌλ‘œ ν• λ‹Ήλœ μ €μž₯곡간 μœ„μΉ˜μ— μ ‘κ·Όν•  수 μžˆλ‹€.

νž™μœΌλ‘œλΆ€ν„° λ™μ μœΌλ‘œ ν• λ‹Ήλ˜λŠ” λ³€μˆ˜λ₯Ό νž™ 동적 λ³€μˆ˜ - Heap-Dynamic Variables 라고 ν•œλ‹€.
λŒ€λΆ€λΆ„ μ‹λ³„μžλ₯Ό λ”°λ‘œ 가지고 μžˆμ§€ μ•Šκ³ , 포인터 λ˜λŠ” μ°Έμ‘° λ³€μˆ˜λ₯Ό ν†΅ν•΄μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
이름 μ—†λŠ” λ³€μˆ˜λ₯Ό 읡λͺ… λ³€μˆ˜ - Anonymous Variables라고 ν•œλ‹€.

2번 μš©λ„μ—μ„œ κ°€μž₯ μ€‘μš”ν•œ 섀계 λ¬Έμ œκ°€ 생긴닀. ν¬μΈν„°λŠ” ν˜•μ‹ μ—°μ‚°μž(* C와 C++, access Ada)λ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜λ˜μ§€λ§Œ, λ°°μ—΄μ΄λ‚˜ λ ˆμ½”λ“œμ™€λŠ” 달리 κ΅¬μ‘°ν™”λœ ν˜•μ‹μ€ μ•„λ‹ˆλ‹€. λ˜ν•œ 데이터λ₯Ό μ €μž₯ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” 것이 μ•„λ‹ˆλΌ, λ‹€λ₯Έ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 데 μ‚¬μš©λ˜κΈ° λ•Œλ¬Έμ— 슀칼라 λ³€μˆ˜μ™€λŠ” λ‹€λ₯΄λ‹€.

이 두 λ²”μ£Όμ˜ λ³€μˆ˜λ₯Ό 각각 μ°Έμ‘° μœ ν˜• - ReferenceTypesκ³Ό κ°’ μœ ν˜• - ValueTypes이라고 ν•œλ‹€.
포인터λ₯Ό μ‚¬μš©ν•˜λŠ” 두 μœ ν˜• λͺ¨λ‘ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ μž‘μ„±λ ₯에 도움을 μ€€λ‹€.

i,e,
포인터가 μ—†λŠ” Fortran 77 같은 μ–Έμ–΄λ‘œ 이진 트리처럼 동적 ꡬ쑰λ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€λ©΄, ν”„λ‘œκ·Έλž˜λ¨Έκ°€ κ°€μš©ν•œ 트리 λ…Έλ“œ 풀을 μ œκ³΅ν•˜κ³  μœ μ§€ν•΄μ•Ό ν•˜λ©°, μ΄λŠ” 병렬 μ–΄λ ˆμ΄λ‘œ κ΅¬ν˜„λ  κ°€λŠ₯성이 λ†’λ‹€. λ˜ν•œ Fortran 77μ—λŠ” 동적 μ €μž₯ 곡간이 μ—†κΈ° λ•Œλ¬Έμ— ν”„λ‘œκ·Έλž˜λ¨Έκ°€ ν•„μš”ν•œ μ΅œλŒ€ λ…Έλ“œ 수λ₯Ό μΆ”μΈ‘ν•΄μ•Ό ν•  것이닀. μ΄λŠ” λΆ„λͺ… μ–΄μƒ‰ν•˜κ³ , 였λ₯˜κ°€ λ°œμƒν•˜κΈ° μ‰¬μš΄ 처리 방법이닀.

μ°Έμ‘° λ³€μˆ˜λŠ” 포인터와 λ°€μ ‘ν•œ 관련이 μžˆλ‹€.

πŸ’« 섀계 문제 - Design Issue

  • 포인터 λ³€μˆ˜μ˜ λ²”μœ„μ™€ 수λͺ…은 μ–Όλ§ˆμΈκ°€?
  • 동적 λ³€μˆ˜(포인터가 μ°Έμ‘°ν•˜λŠ” κ°’)의 수λͺ…은 μ–Όλ§ˆμΈκ°€?
  • 포인터가 κ°€λ¦¬ν‚€λŠ” κ°’μ˜ μœ ν˜•μ— μ œν•œμ΄ μžˆλ‚˜?
  • ν¬μΈν„°μ˜ μš©λ„κ°€ 동적 μŠ€ν† λ¦¬μ§€ 관리, κ°„μ ‘ μ£Όμ†Œ 지정 λ˜λŠ” λ‘˜ λ‹€ 인가?
  • μ–Έμ–΄λŠ” 포인터 μœ ν˜•, μ°Έμ‘° μœ ν˜• λ˜λŠ” λ‘˜ λ‹€λ₯Ό 지원해야 ν•˜λ‚˜?

πŸ’« 포인터 μ—°μ‚°λ“€

포인터 νƒ€μž…μ„ μ œκ³΅ν•˜λŠ” 언어듀은 λŒ€κ°œ 두 가지 기본적인 포인터 연산을 ν¬ν•¨ν•œλ‹€.

  1. ν• λ‹Ή - Assignment
  2. μ—­μ°Έμ‘° - Dereferencing

μ‹μ—μ„œ 포인터 λ³€μˆ˜μ˜ λ°œμƒμ€ 두 가지 λ°©λ²•μœΌλ‘œ 해석할 수 μžˆλ‹€.

  1. 일반적인 μ°Έμ‘° : 포인터 λ°”μΈλ”©λœ λ©”λͺ¨λ¦¬ μ…€ 자체의 λ‚΄μš© μ°Έμ‘°
    • μˆ˜μ‹μ—μ„œ 비포인터 λ³€μˆ˜λŠ” μ •ν™•νžˆ 이런 μ‹μœΌλ‘œ ν•΄μ„λ˜μ§€λ§Œ, κ·Έ κ²½μš°μ—λŠ” 값이 μ£Όμ†Œκ°€ 아닐 κ°€λŠ₯성이 λ†’λ‹€.
  2. 간접적인 μ°Έμ‘° (μ—­μ°Έμ‘°) : 포인터가 λ°”μΈλ”©λœ λ©”λͺ¨λ¦¬ 셀이 κ°€λ¦¬ν‚€λŠ” λ©”λͺ¨λ¦¬ μ…€ λ‚΄μ˜ 값을 μ°Έμ‘°ν•˜λŠ” 것

🫧 ν• λ‹Ή - Assingment

포인터 λ³€μˆ˜μ˜ 값을 μ–΄λ–€ μœ μš©ν•œ μ£Όμ†Œλ‘œ μ„€μ •ν•œλ‹€.
포인터 λ³€μˆ˜λ₯Ό 였직 동적 μ €μž₯곡간 κ΄€λ¦¬μ—λ§Œ μ‚¬μš©ν•œλ‹€λ©΄, ν• λ‹Ή λ©”μ»€λ‹ˆμ¦˜μ€ μ—°μ‚°μžμ— μ˜ν•΄μ„œλ“  λ‚΄μž₯ ν•¨μˆ˜μ— μ˜ν•΄μ„œλ“  포인터 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 역할을 ν•œλ‹€.
포인터 λ³€μˆ˜λ₯Ό 였직 κ°„μ ‘ μ£Όμ†Œ 지정을 μœ„ν•΄μ„œ μ‚¬μš©ν•œλ‹€λ©΄, λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό κ°€μ Έμ˜€λŠ” λͺ…μ‹œμ  μ—°μ‚°μžλ‚˜ λ‚΄μž₯ ν•¨μˆ˜μ΄ μžˆμ–΄μ•Ό 포인터 λ³€μˆ˜μ— ν• λ‹Ήν•  수 μžˆλ‹€.

νž™μ˜ 관리λ₯Ό μœ„ν•œ 포인터λ₯Ό μ œκ³΅ν•˜λŠ” μ–Έμ–΄λŠ” λͺ…μ‹œμ μΈ ν• λ‹Ή 연산을 포함해야 ν•œλ‹€.

C의 mallocκ³Ό 같은 ν•¨μˆ˜λ‘œ μ§€μ •λ˜κΈ°λ„ ν•œλ‹€.

객체 지ν–₯ μ–Έμ–΄μ—μ„œλŠ” νž™ 객체의 할당을 new μ—°μ‚°μžλ‘œ μ§€μ •ν•˜λŠ” κ²½μš°κ°€ λ§Žλ‹€.
암묡적인 ν• λ‹Ή ν•΄μ œλ₯Ό μ œκ³΅ν•˜μ§€ μ•ŠλŠ” C++ deleteλ₯Ό ν• λ‹Ή ν•΄μ œ μ—°μ‚°μžλ‘œ μ‚¬μš©ν•œλ‹€.

🫧 μ—­μ°Έμ‘° - Dereference-ing

ν•œ λ‹¨κ³„μ˜ λ°©ν–₯성을 톡해 μ°Έμ‘°λ₯Ό μ·¨ν•˜λŠ” 것. λͺ…μ‹œμ μ΄κ±°λ‚˜ 암묡적일 수 μžˆλ‹€.

Fortran 95+μ—μ„œ μ•”μ‹œμ μ΄μ§€λ§Œ, λ‹€λ₯Έ λ§Žμ€ ν˜„λŒ€ μ–Έμ–΄μ—μ„œλŠ” λͺ…μ‹œμ μœΌλ‘œ μ§€μ •λœ κ²½μš°μ—λ§Œ λ°œμƒν•œλ‹€.
C++μ—μ„œλŠ” 접두사 단항 μ—°μ‚°μžλ‘œ λ³„ν‘œ(*)와 ν•¨κ»˜ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •λœλ‹€.

i.e.
ptr이 κ°’ 7080인 포인터 λ³€μˆ˜μ΄κ³ , μ£Όμ†Œκ°€ 7080인 μ…€μ˜ 값이 206인 경우,
ν• λ‹Ή β€˜j = *ptr’은 jλ₯Ό 206으둜 μ„€μ •ν•˜λŠ” 것이닀.

포인터가 λ ˆμ½”λ“œλ₯Ό 가리킬 λ•Œ μ΄λŸ¬ν•œ λ ˆμ½”λ“œμ˜ ν•„λ“œμ— λŒ€ν•œ 참쑰의 문법은 μ–Έμ–΄λ§ˆλ‹€ λ‹€λ₯΄λ‹€.

in C/Cpp

  1. (*p.age), 포인터 λ³€μˆ˜ pκ°€ ageλΌλŠ” ν•„λ“œλ₯Ό 가진 λ ˆμ½”λ“œλ₯Ό 가리킬 λ•Œ
  2. p -> age, μ—°μ‚°μž ->λŠ” λ ˆμ½”λ“œμ— λŒ€ν•œ 포인터와 ν•΄λ‹Ή λ ˆμ½”λ“œμ˜ ν•„λ“œ 사이에 μ‚¬μš©λ  λ•Œ 역참쑰와 ν•„λ“œ μ°Έμ‘°λ₯Ό κ²°ν•©

Ada, μ΄λŸ¬ν•œ ν¬μΈν„°μ˜ μ‚¬μš©μ΄ μ•”λ¬΅μ μœΌλ‘œ μ—­μ°Έμ‘°λ˜κΈ° λ•Œλ¬Έμ— p.ageλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

πŸ’« ν¬μΈν„°μ˜ λ¬Έμ œλ“€

포인터 λ³€μˆ˜λ₯Ό ν¬ν•¨ν•œ 졜초의 κ³ μˆ˜μ€€ μ–Έμ–΄ β€˜PL/I’, μ—¬κΈ°μ„œ ν¬μΈν„°λŠ” 동적 λ³€μˆ˜μ™€ λ‹€λ₯Έ λ³€μˆ˜λ₯Ό λͺ¨λ‘ μ°Έμ‘°ν•˜λŠ” 데 μ‚¬μš©λ  수 μžˆμ—ˆλ‹€.

PL/I의 ν¬μΈν„°λŠ” 맀우 μœ μ—°ν–ˆμ§€λ§Œ μ—¬λŸ¬ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆμ—ˆλ‹€.
후속 μ–Έμ–΄λ“€μ˜ 포인터듀에도 PL/I ν¬μΈν„°λ“€μ˜ 문제 쀑 일뢀가 κ·ΈλŒ€λ‘œ μ‘΄μž¬ν•œλ‹€.

졜근 언어듀은 포인터듀을 μ°Έμ‘° ν˜•μ‹μœΌλ‘œ μ™„μ „νžˆ λŒ€μ²΄ν–ˆλŠ”λ°, μ΄λŠ” 암묡적인 ν• λ‹Ή ν•΄μ œμ™€ ν•¨κ»˜ ν¬μΈν„°λ“€μ˜ μ£Όμš” 문제λ₯Ό μ΅œμ†Œν™”ν•œλ‹€. μ°Έμ‘° ν˜•μ‹μ€ μ‹€μ œλ‘œ 연산이 μ œν•œλœ 포인터일 뿐이닀.

🫧 Dangling Pointers

Danling Pointer, Dangling Reference
ν• λ‹Ή ν•΄μ œλœ 동적 λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό ν¬ν•¨ν•˜λŠ” 포인터닀.

λ¬Έμ œκ°€ λ˜λŠ” 이유

  1. κ°€λ¦¬ν‚€λŠ” μœ„μΉ˜κ°€ μ–΄λ–€ μƒˆλ‘œμš΄ 동적 λ³€μˆ˜μ— μž¬ν• λ‹Ή 됐을 수 μžˆλ‹€.
    • μƒˆλ‘œμš΄ λ³€μˆ˜κ°€ 이전 λ³€μˆ˜μ™€ λ™μΌν•œ μœ ν˜•μ΄ μ•„λ‹ˆλΌλ©΄, λŒ•κΈ€λ§ ν¬μΈν„°μ˜ μš©λ„μ— λŒ€ν•œ μœ ν˜• κ²€μ‚¬λŠ” μœ νš¨ν•˜μ§€ μ•Šλ‹€.
    • μƒˆλ‘œμš΄ 동적 λ³€μˆ˜κ°€ λ™μΌν•œ μœ ν˜•μ΄λ”λΌλ„, κ·Έκ²ƒμ˜ μƒˆλ‘œμš΄ 값은 이전 ν¬μΈν„°μ˜ 폐기된 κ°’κ³Ό 관련이 없을 것이닀.
  2. λŒ•κΈ€λ§ 포인터가 동적 λ³€μˆ˜ 값을 λ³€κ²½ν•˜λŠ” 데 μ‚¬μš©λœλ‹€λ©΄, μƒˆλ‘œμš΄ 동적 λ³€μˆ˜μ˜ 값은 파괴될 것이닀.
  3. ν˜„μž¬ μœ„μΉ˜κ°€ μŠ€ν† λ¦¬μ§€ 관리 μ‹œμŠ€ν…œμ— μ˜ν•΄ μΌμ‹œμ μœΌλ‘œ μ‚¬μš©λ˜κ³  μžˆμ„ 수 있고, μ•„λ§ˆλ„ μ‚¬μš© κ°€λŠ₯ν•œ μŠ€ν† λ¦¬μ§€ λΈ”λ‘λ“€μ˜ μ²΄μΈμ—μ„œ ν¬μΈν„°λ‘œ μ‚¬μš©λ  수 μžˆμœΌλ―€λ‘œ, μŠ€ν† λ¦¬μ§€ κ΄€λ¦¬μžκ°€ μ‹€νŒ¨ν•˜λŠ” 원인이 될 수 μžˆλ‹€.

Danling Pointerκ°€ λ§Œλ“€μ–΄μ§€λŠ” κ³Όμ •

  1. μƒˆλ‘œμš΄ 동적 λ³€μˆ˜ 생성, 포인터 p1이 ν•΄λ‹Ή λ³€μˆ˜λ₯Ό 가리킀도둝 μ„€μ •.
  2. 포인터 p2에 p1의 값이 ν• λ‹Ή.
  3. p1이 κ°€λ¦¬ν‚€λŠ” 동적 λ³€μˆ˜λŠ” λͺ…μ‹œμ μœΌλ‘œ ν• λ‹Ή ν•΄μ œλ˜μ§€λ§Œ (p1을 nil둜 μ„€μ •ν•  μˆ˜λ„ 있음), p2λŠ” 연산에 μ˜ν•΄ λ³€κ²½λ˜μ§€ μ•ŠμŒ.
    • 이제 p2λŠ” Danling Pointer.
    • ν• λ‹Ή ν•΄μ œ 연산이 p1을 λ³€κ²½ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ p1κ³Ό p2λŠ” λͺ¨λ‘ Danling Pointer일 것.
    • (λ¬Όλ‘  이것은 Ailiasing의 문제, p1κ³Ό p2λŠ” Aliases.)

i.e.

1
2
3
4
5
6
int * arrayPtr1;
int * arrayPtr2 = new int[100];
arrayPtr1 = arrayPtr2;
delete [] arrayPtr2;
// Now, arrayPtr1 is dangling, because the heap storage
// to which it was pointing has been deallocated.

λ°°μ—΄ Ptr1κ³Ό Ptr2 λͺ¨λ‘ 달링 포인터가 λ˜λŠ”λ°, μ΄λŠ” C++ delete μ—°μ‚°μžκ°€ ν”Όμ—°μ‚°μž ν¬μΈν„°μ˜ 값에 μ•„λ¬΄λŸ° 영ν–₯을 주지 μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.
C++μ—μ„œλŠ” null을 λ‚˜νƒ€λ‚΄λŠ” 0의 할당을 가진 delete μ—°μ‚°μžλ₯Ό 포인터에 따라 μ΄λ™ν•˜λŠ” 것이 일반적이며 μ•ˆμ „ν•©λ‹ˆλ‹€.
동적 λ³€μˆ˜μ˜ λͺ…μ‹œμ μΈ ν• λ‹Ή ν•΄μ œκ°€ λŒ•κΈ€λ§ ν¬μΈν„°μ˜ μ›μΈμ΄λΌλŠ” 점에 μœ μ˜ν•˜μ‹­μ‹œμ˜€.

delete` μ—°μ‚°μžκ°€ ν”Όμ—°μ‚°μž ν¬μΈν„°μ˜ 값에 μ•„λ¬΄λŸ° 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ°°μ—΄ Ptr1κ³Ό Ptr2 λͺ¨λ‘ λŒ•κΈ€λ§ 포인터가 λœλ‹€.
κ°€λ¦¬μΉ˜λ˜ 값이 ν• λ‹Ή ν•΄μ œλœ 포인터에 null을 λ‚˜νƒ€λ‚΄λŠ” 0을 ν• λ‹Ήν•˜λŠ” 의미의 β€˜delete’ μ—°μ‚°μžλ₯Ό λ”°λ₯΄λŠ” 것이 일반적이며 μ•ˆμ „ν•˜λ‹€.

동적 λ³€μˆ˜μ˜ λͺ…μ‹œμ μΈ ν• λ‹Ή ν•΄μ œκ°€ λŒ•κΈ€λ§ ν¬μΈν„°μ˜ μ›μΈμ΄λΌλŠ” 점에 유의.

🫧 Lost Heap-Dynamic Variables

Lost Heap-Dynamic Variables
ν• λ‹Ήλœ 동적 λ³€μˆ˜μ§€λ§Œ, 더 이상 μ‚¬μš©μž ν”„λ‘œκ·Έλž¨μ—μ„œ μ ‘κ·Όν•  수 μ—†λŠ” λ³€μˆ˜λ₯Ό λ§ν•œλ‹€.

μ΄λŸ¬ν•œ λ³€μˆ˜λ“€μ€ μ›λž˜ λͺ©μ μ— μœ μš©ν•˜μ§€ μ•Šκ³  ν”„λ‘œκ·Έλž¨μ—μ„œ μƒˆλ‘œμš΄ μš©λ„λ‘œ μž¬ν• λ‹Ήλ  수 μ—†κΈ° 가비지(garbage)라고도 λΆˆλ¦°λ‹€.

Lost Heap-Dynamic Variablesκ°€ λ§Œλ“€μ–΄μ§€λŠ” κ³Όμ •

  1. 포인터 p1은 μƒˆλ‘œ μƒμ„±λœ 동적 λ³€μˆ˜ Aλ₯Ό 가리킀도둝 μ„€μ •
  2. p1은 λ‚˜μ€‘μ— μƒˆλ‘œ μƒμ„±λœ λ‹€λ₯Έ 동적 λ³€μˆ˜Bλ₯Ό 가리킀도둝 μ„€μ •
    • AλŠ” 이제 μ ‘κ·Όν•  수 μ—†μŒ, μœ μ‹€λ¨. (λ©”λͺ¨λ¦¬ λˆ„μˆ˜ - Memory Leak)

λ©”λͺ¨λ¦¬ λˆ„μˆ˜λŠ” μ–Έμ–΄κ°€ μ•”μ‹œμ  λ˜λŠ” λͺ…μ‹œμ  ν• λ‹Ή ν•΄μ œλ₯Ό μ‚¬μš©ν•˜λŠ”μ§€μ— 관계없이 λ¬Έμ œκ°€ λœλ‹€.

πŸ’« μ–Έμ–΄ 별 포인터 (+ 포인터 문제 ν•΄κ²° 방법)

🫧 Pointers in Ada

포인터λ₯Ό Access νƒ€μž…μ΄λΌκ³  λΆ€λ₯Έλ‹€.

β€˜Dangling Pointer’ λ¬Έμ œλŠ” μ΄λ‘ μ μœΌλ‘œλŠ” Ada의 섀계에 μ˜ν•΄ λΆ€λΆ„μ μœΌλ‘œ μ™„ν™”λœλ‹€.

동적 λ³€μˆ˜κ°€ 포인터 νƒ€μž…μ˜ Scope 끝에 μ•”λ¬΅μ μœΌλ‘œ (선택에 따라) ν• λ‹Ή ν•΄μ œλ  수 μžˆμœΌλ―€λ‘œ, λͺ…μ‹œμ μΈ ν• λ‹Ή ν•΄μ œμ˜ ν•„μš”μ„±μ΄ 크게 쀄어든닀.
κ·ΈλŸ¬λ‚˜ Ada 컴파일러 쀑에 이런 ν˜•νƒœμ˜ 가비지 μ»¬λ ‰μ…˜μ„ κ΅¬ν˜„ν•˜λŠ” κ²½μš°λŠ” 거의 μ—†κΈ° λ•Œλ¬Έμ—, λŒ€λΆ€λΆ„ 이둠적으둜만 이점이 μžˆλ‹€.

동적 λ³€μˆ˜λŠ” 였직 ν•œ μ’…λ₯˜μ˜ λ³€μˆ˜λ§Œ μ ‘κ·Όν•  수 있기 λ•Œλ¬Έμ—, ν•΄λ‹Ή νƒ€μž… μ„ μ–Έμ˜ Scope 끝에 λ„λ‹¬ν•˜λ©΄ 동적 λ³€μˆ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터λ₯Ό 남길 수 μ—†λ‹€.
이러면 λ¬Έμ œκ°€ 쀄어든닀.

λͺ…μ‹œμ  ν• λ‹Ή ν•΄μ œμΈ Unchecked_Deallocation도 있긴 ν•˜μ§€λ§Œ, Dangling-pointerλ₯Ό λ°œμƒμ‹œν‚¬ 수 μžˆκΈ°μ—, 이름을 톡해 잠재적인 문제λ₯Ό κ²½κ³ ν•˜κ³  μžˆλ‹€.

β€˜Lost Heap-Dynamic Variables’ λ¬Έμ œλŠ” μ„€κ³„λ‘œ ν•΄κ²°λ˜μ§€ μ•ŠλŠ”λ‹€.

🫧 Pointers in C and C++

μ£Όμ†Œκ°€ μ–΄μ…ˆλΈ”λ¦¬ μ–Έμ–΄μ—μ„œ μ‚¬μš©λ˜λŠ” 것과 같은 λ°©μ‹μœΌλ‘œ 포인터λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ”λ°,
μ΄λŠ” 맀우 μœ μ—°ν•˜μ§€λ§Œ μ£Όμ˜ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό 함을 μ˜λ―Έν•œλ‹€. μ΄λŸ¬ν•œ μ„€κ³„λŠ” 포인터 λ¬Έμ œλ“€μ— λŒ€ν•œ 해결책을 μ œκ³΅ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

κ·ΈλŸ¬λ‚˜ C/C++μ—μ„œ 포인터 연산이 κ°€λŠ₯ν•˜λ‹€λŠ” 사싀은 λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ° 언어보닀 포인터가 더 ν₯미둭게 λ§Œλ“ λ‹€. (리슀크/리턴)

C와 C++ ν¬μΈν„°λŠ” ν• λ‹Ήλœ μœ„μΉ˜μ— 관계없이 μž„μ˜μ˜ λ³€μˆ˜λ₯Ό 가리킬 수 μžˆλ‹€.
μ‹€μ œλ‘œ ν¬μΈν„°μ˜ μœ„ν—˜ 쀑 ν•˜λ‚˜μΈ λ³€μˆ˜κ°€ μ‘΄μž¬ν•˜λ“  μ‘΄μž¬ν•˜μ§€ μ•Šλ“  λ©”λͺ¨λ¦¬μ˜ μ–΄λŠ 곳을 가리킬 수 μžˆλ‹€.
두 μ½”λ“œλŠ” μ˜λ―Έκ°€ κ°™λ‹€.

1
2
3
4
5
6
7
int *ptr;
int count, init;

// ...

ptr = &init;
count = *ptr;
1
2
int count, init;
count = init;

일뢀 μ œν•œλœ ν˜•μ‹μœΌλ‘œ Pointer 연산이 κ°€λŠ₯ν•˜λ‹€.

예λ₯Ό λ“€μ–΄, ptr이 일뢀 데이터 μœ ν˜•μ˜ λ³€μˆ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” κ²ƒμœΌλ‘œ μ„ μ–Έλœ 포인터 λ³€μˆ˜λΌλ©΄ β€˜ptr + indexβ€™λŠ” 합법적인 ν‘œν˜„μ‹μž…λ‹ˆλ‹€.
ptrμ—μ„œ (ptr이 λŒ€μƒμœΌλ‘œ ν•˜λŠ” νƒ€μž… 크기 * index) 만큼 떨어진 λ©”λͺ¨λ¦¬ 셀을 가리킨닀.
μ΄λŸ¬ν•œ μ£Όμ†Œ μ—°μ‚°μ˜ 주된 λͺ©μ μ€ λ°°μ—΄ μ‘°μž‘μ΄λ‹€.

(1차원 배열에 λŒ€ν•΄ ) C/C++μ—μ„œ λͺ¨λ“  배열은 첨자 λ²”μœ„μ˜ ν•˜ν•œμœΌλ‘œ 0을 μ‚¬μš©ν•˜λ©°, μ²¨μžκ°€ μ—†λŠ” λ°°μ—΄ 이름은 항상 첫 번째 μš”μ†Œμ˜ μ£Όμ†Œλ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

1
2
3
4
int list [10];
int *ptr;

ptr = list;
  • *(ptr + 1)λŠ” list[1]
  • *(ptr + index)λŠ” list[index]
  • ptr[index]λŠ” list[index]

포인터 연산이 인덱싱 μ—°μ‚°μ—μ„œ μ‚¬μš©λ˜λŠ” 것과 같은 μŠ€μΌ€μΌλ§μ„ ν¬ν•¨ν•œλ‹€λŠ” 것이 λΆ„λͺ…ν•˜λ‹€.
배열에 λŒ€ν•œ 포인터듀은 λ°°μ—΄ 이름인 κ²ƒμ²˜λŸΌ 인덱싱될 수 μžˆλ‹€.

포인터듀은 λ§€κ°œλ³€μˆ˜ 전달에도 μ‚¬μš©λœλ‹€.
C/C++λŠ” μ–΄λ–€ ν˜•μ‹μ˜ 값이든 가리킬 수 μžˆλŠ” 일반적인 포인터, void* 포인터듀을 μ΄μš©ν•œλ‹€.

C/C++의 포인터듀은 ν•¨μˆ˜λ“€μ„ 가리킬 수 μžˆλ‹€.
λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 ν•¨μˆ˜λ“€μ„ λ‹€λ₯Έ ν•¨μˆ˜μ— μ „λ‹¬ν•˜λŠ” 데 μ‚¬μš©λœλ‹€.

πŸ’« Reference Type


Reference Type은 포인터와 λΉ„μŠ·ν•˜μ§€λ§Œ, μ€‘μš”ν•˜κ³  기본적인 차이점이 μžˆλ‹€.

ν¬μΈν„°λŠ” λ©”λͺ¨λ¦¬ λ‚΄μ˜ μ£Όμ†Œλ₯Ό μ˜λ―Έν•˜κ³ ,
μ°Έκ³ ν˜•μ€ λ©”λͺ¨λ¦¬ λ‚΄μ˜ κ°μ²΄λ‚˜ 값을 μ˜λ―Έν•œλ‹€.

λ”°λΌμ„œ,
μ£Όμ†Œμ— λŒ€ν•΄μ„œλŠ” 연산을 μˆ˜ν–‰ν•˜λŠ” 것이 λ‹Ήμ—°ν•˜μ§€λ§Œ
μ°Έκ³ ν˜•μ— λŒ€ν•΄μ„œλŠ” 연산을 μˆ˜ν–‰ν•˜λŠ” 것이 μ μ ˆν•˜μ§€ μ•Šλ‹€.

C++λŠ” ν•¨μˆ˜ μ •μ˜μ—μ„œ 곡식 λ§€κ°œλ³€μˆ˜μ— 주둜 μ‚¬μš©λ˜λŠ” νŠΉμˆ˜ν•œ μ’…λ₯˜μ˜ μ°Έμ‘°ν˜•μ΄ μžˆλ‹€.
C++ μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” 항상 μ•”λ¬΅μ μœΌλ‘œ λ””λ ˆνΌλŸ°μŠ€λ˜λŠ” μƒμˆ˜ ν¬μΈν„°μž…λ‹ˆλ‹€.
C++ μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” μƒμˆ˜μ΄λ―€λ‘œ μ •μ˜μ—μ„œ μ–΄λ–€ λ³€μˆ˜μ˜ μ£Όμ†Œλ‘œ μ΄ˆκΈ°ν™”λ˜μ–΄μ•Ό ν•˜λ©°,
μ΄ˆκΈ°ν™” ν›„μ—λŠ” μ ˆλŒ€λ‘œ λ‹€λ₯Έ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ μ„€μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
암묡적 λ””λ ˆνΌλŸ°μŠ€λŠ” μ°Έμ‘° λ³€μˆ˜μ˜ μ£Όμ†Œ 값에 ν• λ‹Ήλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” μ•°νΌμƒŒλ“œ(&)둜 이름 μ•žμ— λΆ™μ—¬ μ •μ˜λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄,

1
2
3
result = 0;
int &ref_ result = result;
ref_result = 100;

이 μ½”λ“œ μ„Έκ·Έλ¨ΌνŠΈμ—μ„œ result 및 ref_resultλŠ” 별칭(λ™μ˜μ–΄)이닀.

ν•¨μˆ˜ μ •μ˜μ—μ„œ ν˜•μ‹ λ§€κ°œλ³€μˆ˜λ‘œ μ‚¬μš©λ˜λŠ” 경우 C++ μ°Έμ‘° μœ ν˜•μ€ 호좜자 ν•¨μˆ˜μ™€ 호좜된 ν•¨μˆ˜ κ°„μ˜ μ–‘λ°©ν–₯ 톡신을 μ œκ³΅ν•œλ‹€.
C++ λ§€κ°œλ³€μˆ˜λŠ” κ°’μœΌλ‘œ μ „λ‹¬λ˜κΈ° λ•Œλ¬Έμ— 비포인터 ν”„λ¦¬λ―Έν‹°λΈŒ λ§€κ°œλ³€μˆ˜ μœ ν˜•μ—μ„œλŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.
포인터λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λ©΄ λ™μΌν•œ μ–‘λ°©ν–₯ 톡신이 μˆ˜ν–‰λ˜μ§€λ§Œ 포인터 ν˜•μ‹ λ§€κ°œλ³€μˆ˜λŠ” λͺ…μ‹œμ μΈ μ—­μ°Έμ‘°λ₯Ό ν•„μš”λ‘œ ν•˜λ―€λ‘œ μ½”λ“œμ˜ 가독성과 μ•ˆμ „μ„±μ΄ 떨어진닀.
μ°Έμ‘° λ§€κ°œλ³€μˆ˜λŠ” λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 호좜된 ν•¨μˆ˜μ—μ„œ μ •ν™•νžˆ μ°Έμ‘°λœλ‹€.
호좜 ν•¨μˆ˜λŠ” ν•΄λ‹Ή ν˜•μ‹ λ§€κ°œλ³€μˆ˜κ°€ μ°Έμ‘° μœ ν˜•μΈ λ§€κ°œλ³€μˆ˜κ°€ νŠΉμ΄ν•œ κ²ƒμž„μ„ 지정할 ν•„μš”κ°€ μ—†λ‹€.
μ»΄νŒŒμΌλŸ¬λŠ” μ°Έμ‘° λ§€κ°œλ³€μˆ˜μ— 값이 μ•„λ‹Œ μ£Όμ†Œλ₯Ό μ „λ‹¬ν•œλ‹€.

JavaλŠ” μ•ˆμ „μ„±μ„ 높이기 μœ„ν•΄ C++ μŠ€νƒ€μΌμ˜ 포인터λ₯Ό μ•„μ˜ˆ μ œκ±°ν–ˆλ‹€.
Java μ°Έμ‘° λ³€μˆ˜λŠ”, C++ μ°Έμ‘° λ³€μˆ˜μ™€ 달리 μƒμˆ˜κ°€ μ•„λ‹ˆλΌ μ„œλ‘œ λ‹€λ₯Έ 클래슀 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ 지정할 수 μžˆλ‹€.
λͺ¨λ“  μžλ°” 클래슀 μΈμŠ€ν„΄μŠ€λŠ” μ°Έμ‘° λ³€μˆ˜μ— μ˜ν•΄ μ°Έμ‘°λœλ‹€.

1
2
String str1; // null
str1 = "This is a Java literal string.";

str1은 String 클래슀 μΈμŠ€ν„΄μŠ€ λ˜λŠ” κ°œμ²΄μ— λŒ€ν•œ 참쑰둜 μ •μ˜λœλ‹€.
μ΄ˆκΉƒκ°’ null, 이후 str1이 String 개체인 β€œThis is a Java literal string.”λ₯Ό μ°Έμ‘°.

C#, Java 클래슀 μΈμŠ€ν„΄μŠ€λŠ” μ•”λ¬΅μ μœΌλ‘œ ν• λ‹Ή ν•΄μ œλ˜λ―€λ‘œ (λͺ…μ‹œμ  ν• λ‹Ή ν•΄μ œ μ—°μ‚°μžκ°€ μ—†μŒ) Javaμ—λŠ” dangling referenceκ°€ μžˆμ„ 수 μ—†λ‹€.

C#은 참쑰와 포인터λ₯Ό λͺ¨λ‘ 가진닀.
ν•˜μ§€λ§Œ 포인터λ₯Ό μ‚¬μš©ν•˜λŠ” 것은 κ°•λ ₯히 ꢌμž₯λ˜μ§€ μ•ŠλŠ”λ‹€. (포인터λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ unsafe μˆ˜μ‹μ–΄λ₯Ό 포함)
참쑰둜 가리킨 κ°μ²΄λŠ” μ•”λ¬΅μ μœΌλ‘œ ν• λ‹Ή ν•΄μ œλ˜μ§€λ§Œ, ν¬μΈν„°λ‘œ 가리킨 객체의 κ²½μš°μ—λŠ” 그렇지 μ•ŠλŠ”λ‹€.
C/C++ μ½”λ“œμ™€ μƒν˜Έ μž‘μš©ν•  수 μžˆλ„λ‘ 포함됐닀.

개체 지ν–₯ 언어인 Smalltalk, Python, Ruby, Lua의 λͺ¨λ“  λ³€μˆ˜λŠ” μ°Έμ‘°λ‹€.
이듀은 항상 μ•”λ¬΅μ μœΌλ‘œ μ°Έμ‘° ν•΄μ œλœλ‹€.
κ²Œλ‹€κ°€ 이 λ³€μˆ˜λ“€μ˜ 직접적인 값은 μ ‘κ·Όν•  수 μ—†λ‹€.

πŸ’« 평가


Lost Heap-Dynamic Variables, Danling Pointer

Pointer vs goto
goto 문은 λ‹€μŒμ— 싀행될 수 μžˆλŠ” λ¬Έμž₯의 λ²”μœ„λ₯Ό λ„“νž™λ‹ˆλ‹€.
포인터 λ³€μˆ˜λŠ” λ³€μˆ˜κ°€ μ°Έμ‘°ν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬ μ…€μ˜ λ²”μœ„λ₯Ό λ„“νžŒλ‹€.

반면 ν¬μΈν„°λŠ” μ–΄λ–€ μ’…λ₯˜μ˜ ν”„λ‘œκ·Έλž˜λ° μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ ν•„μˆ˜μ μ΄λ‹€.
예λ₯Ό λ“€μ–΄ ν¬μΈν„°λŠ” νŠΉμ •ν•œ μ ˆλŒ€ μ£Όμ†Œμ— μ ‘κ·Όν•΄μ•Ό ν•˜λŠ” μž₯치 λ“œλΌμ΄λ²„λ₯Ό μž‘μ„±ν•˜λŠ” 데 ν•„μš”ν•˜λ‹€.

μžλ°”μ™€ C#의 μ°Έμ‘°λŠ” μœ„ν—˜ μš”μ†Œ 없이 ν¬μΈν„°μ˜ μœ μ—°μ„±κ³Ό κΈ°λŠ₯을 μ–΄λŠ 정도 μ œκ³΅ν•œλ‹€.
ν”„λ‘œκ·Έλž˜λ¨Έλ“€μ΄ 참쑰의 μ•ˆμ „μ„±μ„ 더 μ€‘μš”μ‹œ ν•˜μ—¬ C와 C++ ν¬μΈν„°μ˜ μ™„μ „ν•œ νž˜μ„ 기꺼이 κ΅ν™˜ν• μ§€λŠ” 두고 봐야 ν•  것.
C# ν”„λ‘œκ·Έλž¨μ΄ 포인터λ₯Ό μ‚¬μš©ν•˜λŠ” 정도가 μ΄κ²ƒμ˜ ν•œ 척도가 될 것.

πŸ’« Implementation of Pointer and Reference Types


λŒ€λΆ€λΆ„μ˜ μ–Έμ–΄μ—μ„œ ν¬μΈν„°λŠ” νž™ 관리에 μ‚¬μš©λœλ‹€.
Smalltalk와 Ruby의 λ³€μˆ˜λΏλ§Œ μ•„λ‹ˆλΌ Java와 C# 참쑰도 λ§ˆμ°¬κ°€μ§€μ΄λ―€λ‘œ 포인터와 μ°Έμ‘°λ₯Ό λ”°λ‘œ λ‹€λ£° 수 μ—†λ‹€.

🫧 Representations of Pointers and References

λŒ€λΆ€λΆ„μ˜ μ»΄ν“¨ν„°μ—μ„œ 포인터와 μ°Έμ‘°λŠ” λ©”λͺ¨λ¦¬ 셀에 μ €μž₯된 단일 값이닀.
κ·ΈλŸ¬λ‚˜ 인텔 λ§ˆμ΄ν¬λ‘œν”„λ‘œμ„Έμ„œλ₯Ό 기반으둜 ν•˜λŠ” 초기의 λ§ˆμ΄ν¬λ‘œμ»΄ν“¨ν„°μ—μ„œλŠ” μ£Όμ†Œκ°€ μ„Έκ·Έλ¨ΌνŠΈμ™€ μ˜€ν”„μ…‹ 두 λΆ€λΆ„μœΌλ‘œ κ΅¬μ„±λœλ‹€.
λ”°λΌμ„œ μ΄λŸ¬ν•œ μ‹œμŠ€ν…œμ—μ„œ 포인터와 μ°Έμ‘°λŠ” 16λΉ„νŠΈ μ…€ 쌍으둜 κ΅¬ν˜„λ˜λ©°, μ£Όμ†Œμ˜ 두 λΆ€λΆ„ 각각에 λŒ€ν•΄ ν•˜λ‚˜μ”© κ΅¬ν˜„λœλ‹€.

🫧 Solutions to the Dangling-Pointer Problem

Dangling-Pointer λ¬Έμ œμ— λŒ€ν•œ 해결책은 μ—¬λŸ¬ 가지가 μ œμ•ˆλλ‹€.

λ¬Όλ‘ , μ΅œμ„ μ˜ 해결책은 동적 λ³€μˆ˜λ“€μ˜ 할당을 ν”„λ‘œκ·Έλž˜λ¨Έμ˜ μ†μ—μ„œ μ—†μ• λŠ” 것이닀.
ν”„λ‘œκ·Έλž¨λ“€μ΄ 동적 λ³€μˆ˜λ“€μ˜ 할당을 λͺ…μ‹œμ μœΌλ‘œ ν•΄μ œν•  수 μ—†λ‹€λ©΄, Dangling-Pointer듀은 없을 κ²ƒμž…λ‹ˆλ‹€.

이λ₯Ό μœ„ν•΄μ„œλŠ” λŸ°νƒ€μž„ μ‹œμŠ€ν…œμ΄ 동적 λ³€μˆ˜λ“€μ΄ 더 이상 μ“Έλͺ¨κ°€ 없을 λ•Œ μ•”λ¬΅μ μœΌλ‘œ 할당을 ν•΄μ œν•΄μ•Ό ν•œλ‹€.
LISP μ‹œμŠ€ν…œλ“€μ€ 항상 μ΄λ ‡κ²Œ ν•΄μ™”κ³ , Java와 C# λͺ¨λ‘ μ°Έμ‘° λ³€μˆ˜λ“€μ— λŒ€ν•΄μ„œ 이 접근법을 μ‚¬μš©ν•œλ‹€.
C#의 ν¬μΈν„°λ“€μ—λŠ” 암묡적인 ν• λ‹Ή ν•΄μ œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμŒμ„ κΈ°μ–΅.

Tombstones

λͺ¨λ“  동적 λ³€μˆ˜κ°€ 동적 λ³€μˆ˜μ— λŒ€ν•œ 포인터인 β€˜Tombstone’이라고 λΆˆλ¦¬λŠ” 특수 셀을 ν¬ν•¨ν•˜λŠ” Tombstones.

μ‹€μ œ 포인터 λ³€μˆ˜λŠ” β€˜Tombstoneβ€™μ—λ§Œ 있고 동적 λ³€μˆ˜λŠ” μ ˆλŒ€ κ°€λ¦¬ν‚€λŠ” 것이 μ•„λ‹ˆλ‹€.
동적 λ³€μˆ˜κ°€ ν• λ‹Ή ν•΄μ œλ˜λ©΄ β€˜Tombstone’은 κ·ΈλŒ€λ‘œ μœ μ§€λ˜μ§€λ§Œ β€˜0β€™μœΌλ‘œ μ„€μ •λ˜μ–΄ 동적 λ³€μˆ˜κ°€ 더 이상 μ‘΄μž¬ν•˜μ§€ μ•ŠμŒμ„ λ‚˜νƒ€λ‚Έλ‹€.
이 접근법은 포인터가 ν• λ‹Ή ν•΄μ œλœ λ³€μˆ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” 것을 λ°©μ§€ν•œλ‹€.
0이 μ•„λ‹Œ β€˜Tombstone’을 κ°€λ¦¬ν‚€λŠ” 포인터에 λŒ€ν•œ λͺ¨λ“  μ°Έμ‘°λŠ” 였λ₯˜λ‘œ 탐지될 수 μžˆλ‹€.

β€˜Tombstone’은 μ‹œκ°„μ μœΌλ‘œλ‚˜ κ³΅κ°„μ μœΌλ‘œλ‚˜ λΉ„μš©μ΄ 많이 λ“ λ‹€.
β€˜Tombstone’은 κ²°μ½” 할당이 ν•΄μ œλ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, κ·Έ μ €μž₯곡간은 λ‹€μ‹œ ν™•λ³΄λ˜μ§€ μ•ŠλŠ”λ‹€.
νž™ 동적 λ³€μˆ˜μ— μ ‘κ·Όν•  λ•Œλ§ˆλ‹€ ν•œ λ‹¨κ³„μ˜ λ°©ν–₯ μ „ν™˜μ΄ 더 ν•„μš”ν•˜κ³ , λŒ€λΆ€λΆ„μ˜ μ»΄ν“¨ν„°μ—μ„œ 좔가적인 기계 사이클이 ν•„μš”ν•˜λ‹€.

널리 μ‚¬μš©λ˜λŠ” μ–Έμ–΄λ“€ 쀑 β€˜Tombstone’λ₯Ό μ“°λŠ” μ–Έμ–΄κ°€ μ—†λ‹€.
β†’ μ–Έμ–΄ μ„€κ³„μžλ“€ 쀑 κ·Έ λˆ„κ΅¬λ„ κ·Έ 좔가적인 μ•ˆμ „μ„±μ΄ μ΄λŸ¬ν•œ 좔가적인 λΉ„μš©μ˜ κ°€μΉ˜κ°€ μžˆλ‹€κ³  μƒκ°ν•˜μ§€ μ•ŠμŒ.

Locks-and-Keys Approach

UW-Pascal κ΅¬ν˜„μ— μ‚¬μš©λ˜λŠ” Locks-and-Keys 접근법.

이 μ»΄νŒŒμΌλŸ¬μ—μ„œ 포인터 값은 μˆœμ„œμŒ(key, address)으둜 ν‘œν˜„λ˜λ©°, μ—¬κΈ°μ„œ ν‚€λŠ” μ •μˆ˜ 값이닀.
동적 λ³€μˆ˜λŠ” λ³€μˆ˜μ˜ μ €μž₯μ†Œμ— μ •μˆ˜ 잠금 값을 μ €μž₯ν•˜λŠ” 헀더 셀을 λ”ν•œ κ°’μœΌλ‘œ ν‘œν˜„λœλ‹€.
동적 λ³€μˆ˜κ°€ ν• λ‹Ήλ˜λ©΄ 잠금 값이 μƒμ„±λ˜μ–΄ 동적 λ³€μˆ˜μ˜ 잠금 μ…€κ³Ό β€˜new’ ν˜ΈμΆœμ— μ§€μ •λœ ν¬μΈν„°μ˜ ν‚€ 셀에 λͺ¨λ‘ λ°°μΉ˜λœλ‹€.
λ””λ ˆνΌλŸ°λ“œ 포인터에 λŒ€ν•œ λͺ¨λ“  μ ‘κ·Όμ—μ„œ, ν¬μΈν„°μ˜ ν‚€ 값을 동적 λ³€μˆ˜μ˜ 잠금 κ°’κ³Ό λΉ„κ΅ν•œλ‹€.
μΌμΉ˜ν•˜λ©΄ μ•‘μ„ΈμŠ€λŠ” 합법이고, μΌμΉ˜ν•˜μ§€ μ•ŠμœΌλ©΄ λŸ°νƒ€μž„ 였λ₯˜λ‘œ μ²˜λ¦¬λœλ‹€.
λ‹€λ₯Έ 포인터에 λŒ€ν•œ 포인터 κ°’μ˜ 볡사본은 ν‚€ 값을 볡사해야 ν•œλ‹€.
λ”°λΌμ„œ μ–΄λ–€ 수의 포인터라도 주어진 동적 λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.

동적 λ³€μˆ˜κ°€ β€˜dis-poseβ€™λ‘œ 할당이 ν•΄μ œλ˜λ©΄ ν•΄λ‹Ή ν¬μΈν„°μ˜ 잠금 값은 잘λͺ»λœ 잠금 κ°’μœΌλ‘œ μ§€μ›Œμ§„λ‹€.
그러면 β€˜dis-pose’에 μ§€μ •λœ 포인터가 μ•„λ‹Œ λ‹€λ₯Έ 포인터가 λ””λ ˆνΌλŸ°λ“œλ˜λ©΄ μ£Όμ†Œ 값은 κ·ΈλŒ€λ‘œ μœ μ§€λ˜μ§€λ§Œ, ν‚€ 값은 더 이상 잠금과 μΌμΉ˜ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ μ•‘μ„ΈμŠ€κ°€ ν—ˆμš©λ˜μ§€ μ•ŠλŠ”λ‹€.

🫧 Heap Management

νž™ κ΄€λ¦¬λŠ” 맀우 λ³΅μž‘ν•œ λŸ°νƒ€μž„ ν”„λ‘œμ„ΈμŠ€κ°€ 될 수 μžˆλ‹€.

κΈ€μ—μ„œλŠ” ν• λ‹Ή ν•΄μ œμ˜ 경우 암묡적인 μ ‘κ·Ό λ°©μ‹λ§Œ λ…Όμ˜.
ν”„λ‘œμ„ΈμŠ€ 및 κ΄€λ ¨ λ¬Έμ œμ— λŒ€ν•œ μ² μ €ν•œ 뢄석은 κ΅¬ν˜„ 문제만큼, μ–Έμ–΄ 섀계 λ¬Έμ œκ°€ μ•„λ‹ˆλ‹€.

Single-Size Cells

κ°€μž₯ κ°„λ‹¨ν•œ 상황은 λͺ¨λ“  ν• λ‹Ήκ³Ό ν• λ‹Ή ν•΄μ œκ°€ 단일 크기의 셀인 κ²½μš°μž…λ‹ˆλ‹€. λͺ¨λ“  셀에 이미 포인터가 μžˆμ„ λ•Œ λ”μš± λ‹¨μˆœν™”λ©λ‹ˆλ‹€. 동적 μŠ€ν† λ¦¬μ§€ ν• λ‹Ήμ˜ λ¬Έμ œκ°€ λŒ€κ·œλͺ¨λ‘œ 처음 μ ‘ν–ˆλ˜ LISP의 λ§Žμ€ κ΅¬ν˜„λ“€μ˜ μ‹œλ‚˜λ¦¬μ˜€μž…λ‹ˆλ‹€. λͺ¨λ“  LISP ν”„λ‘œκ·Έλž¨λ“€κ³Ό λŒ€λΆ€λΆ„μ˜ LISP λ°μ΄ν„°λŠ” 링크된 λͺ©λ‘μ˜ μ…€λ“€λ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

단일 크기의 ν• λ‹Ή νž™μ—μ„œλŠ” μ‚¬μš© κ°€λŠ₯ν•œ λͺ¨λ“  셀듀이 μ…€ μ•ˆμ˜ 포인터듀을 μ‚¬μš©ν•˜μ—¬ μ„œλ‘œ μ—°κ²°λ˜μ–΄ μ‚¬μš© κ°€λŠ₯ν•œ κ³΅κ°„μ˜ λͺ©λ‘μ„ λ§Œλ“ λ‹€. 할당은 ν•„μš”ν•  λ•Œ ν•„μš”ν•œ 수의 셀을 이 λͺ©λ‘μ—μ„œ κ°€μ Έμ˜€λŠ” κ°„λ‹¨ν•œ λ¬Έμ œμ΄λ‹€. ν• λ‹Ή ν•΄μ œλŠ” 훨씬 더 λ³΅μž‘ν•œ 과정이닀. νž™-동적 λ³€μˆ˜λŠ” ν•˜λ‚˜ μ΄μƒμ˜ ν¬μΈν„°λ‘œ 가리킬 수 μžˆμœΌλ―€λ‘œ, μ–Έμ œ κ·Έ λ³€μˆ˜κ°€ ν”„λ‘œκ·Έλž¨μ— 더 이상 μ“Έλͺ¨κ°€ μ—†λŠ”μ§€ νŒλ‹¨ν•˜κΈ°κ°€ μ–΄λ ΅λ‹€. λ‹¨μˆœνžˆ ν•˜λ‚˜μ˜ 포인터가 μ…€μ—μ„œ λΆ„λ¦¬λ˜μ—ˆλ‹€κ³  ν•΄μ„œ 그것이 μ“°λ ˆκΈ°κ°€ λ˜λŠ” 것은 μ•„λ‹ˆλ©°, 셀을 κ°€λ¦¬ν‚€λŠ” λ‹€λ₯Έ 포인터듀도 μ—¬λŸ¬ 개 μ‘΄μž¬ν•  수 μžˆλ‹€.

LISPμ—μ„œλŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ κ°€μž₯ λΉˆλ²ˆν•œ μž‘μ—… 쀑 λͺ‡ κ°€μ§€λŠ” 더 이상 ν”„λ‘œκ·Έλž¨μ— μ ‘κ·Όν•  수 μ—†μœΌλ―€λ‘œ ν• λ‹Ή ν•΄μ œ(μ‚¬μš© κ°€λŠ₯ν•œ 곡간 λͺ©λ‘μ— λ‹€μ‹œ μ˜¬λ €λ†“μŒ)ν•΄μ•Ό ν•˜λŠ” μ…€ λͺ¨μŒμ„ λ§Œλ“­λ‹ˆλ‹€. LISP의 κΈ°λ³Έ 섀계 λͺ©ν‘œ 쀑 ν•˜λ‚˜λŠ” μ‚¬μš©λ˜μ§€ μ•Šμ€ μ…€μ˜ νšŒμˆ˜κ°€ ν”„λ‘œκ·Έλž˜λ¨Έμ˜ κ³Όμ œκ°€ μ•„λ‹ˆλΌ λŸ°νƒ€μž„ μ‹œμŠ€ν…œμ˜ κ³Όμ œκ°€ λ˜λ„λ‘ ν•˜λŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€. 이 λͺ©ν‘œλŠ” LISP μ‹œν–‰μžλ“€μ—κ²Œ κΈ°λ³Έ 섀계 μ§ˆλ¬Έμ„ λ‚¨κ²ΌμŠ΅λ‹ˆλ‹€: μ–Έμ œ ν• λ‹Ή ν•΄μ œλ₯Ό μˆ˜ν–‰ν•΄μ•Ό ν•˜λŠ”κ°€?

μ“°λ ˆκΈ° μˆ˜κ±°μ—λŠ” μ—¬λŸ¬ 가지 λ‹€λ₯Έ μ ‘κ·Ό 방식이 μžˆμŠ΅λ‹ˆλ‹€. κ°€μž₯ 일반적인 두 가지 전톡적인 κΈ°μˆ μ€ μ–΄λ–€ λ©΄μ—μ„œλŠ” λ°˜λŒ€μ˜ κ³Όμ •μž…λ‹ˆλ‹€. 이것듀은 맀립이 증뢄이고 μ ‘κ·Όν•  수 μ—†λŠ” 셀이 생성될 λ•Œ μˆ˜ν–‰λ˜λŠ” μ°Έμ‘° μΉ΄μš΄ν„°μ™€ μ‚¬μš© κ°€λŠ₯ν•œ 곡간 λͺ©λ‘μ΄ λΉ„μ–΄μžˆμ„ λ•Œλ§Œ 맀립이 λ°œμƒν•˜λŠ” 마크 μŠ€μœ„ν”„λΌκ³  λΆˆλ¦½λ‹ˆλ‹€. 이 두 가지 방법은 λ•Œλ•Œλ‘œ 열정적인 접근법과 게으λ₯Έ 접근법이라고 λΆˆλ¦½λ‹ˆλ‹€. 이 두 가지 μ ‘κ·Όλ²•μ˜ λ§Žμ€ λ³€ν˜•μ΄ κ°œλ°œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 이 μ„Ήμ…˜μ—μ„œλŠ” 기본적인 과정에 λŒ€ν•΄μ„œλ§Œ λ…Όμ˜ν•©λ‹ˆλ‹€.

μ €μž₯ 회수의 μ°Έμ‘° μΉ΄μš΄ν„° 방법은 ν˜„μž¬ 셀을 κ°€λ¦¬ν‚€λŠ” ν¬μΈν„°μ˜ 수λ₯Ό μ €μž₯ν•˜λŠ” μΉ΄μš΄ν„°λ₯Ό λͺ¨λ“  셀에 μœ μ§€ν•¨μœΌλ‘œμ¨ λͺ©ν‘œλ₯Ό λ‹¬μ„±ν•©λ‹ˆλ‹€. μ°Έμ‘° μΉ΄μš΄ν„°μ— λŒ€ν•œ κ°μ†Œ 연산에 ν¬ν•¨λœ κ²ƒμœΌλ‘œμ„œ, 포인터가 μ…€μ—μ„œ 뢄리될 λ•Œ λ°œμƒν•˜λŠ” 것은 0 값에 λŒ€ν•œ μ²΄ν¬μž…λ‹ˆλ‹€. μ°Έμ‘° μΉ΄μš΄ν„°κ°€ 0에 λ„λ‹¬ν•˜λ©΄ ν”„λ‘œκ·Έλž¨ 포인터가 셀을 κ°€λ¦¬ν‚€λŠ” 것이 μ—†μŒμ„ μ˜λ―Έν•˜λ©°, λ”°λΌμ„œ 가비지가 λ˜μ–΄ μ‚¬μš© κ°€λŠ₯ν•œ 곡간 λͺ©λ‘μœΌλ‘œ 되돌릴 수 μžˆμŠ΅λ‹ˆλ‹€.

Variable-Size Cells

κ°€λ³€ν¬κΈ°μ˜ μ…€9이 ν• λ‹Ήλœ νž™μ„ κ΄€λ¦¬ν•˜λŠ” 것은 λ‹¨μΌν¬κΈ°μ˜ 셀을 κ΄€λ¦¬ν•˜λŠ” 데에 λ§Žμ€ 어렀움이 μžˆμ§€λ§Œ 좔가적인 λ¬Έμ œμ λ„ μžˆμŠ΅λ‹ˆλ‹€. μ•ˆνƒ€κΉκ²Œλ„ λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œλŠ” κ°€λ³€ν¬κΈ°μ˜ 셀이 ν•„μš”ν•©λ‹ˆλ‹€. κ°€λ³€ν¬κΈ°μ˜ μ…€ κ΄€λ¦¬λ‘œ 인해 μ œκΈ°λ˜λŠ” 좔가적인 λ¬Έμ œμ λ“€μ€ μ‚¬μš©λ˜λŠ” 방법에 따라 λ‹¬λΌμ§‘λ‹ˆλ‹€. 마크 μŠ€μœ„ν”„λ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같은 좔가적인 λ¬Έμ œμ λ“€μ΄ λ°œμƒν•©λ‹ˆλ‹€:

β€’ μ“°λ ˆκΈ°μž„μ„ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ 더미에 μžˆλŠ” λͺ¨λ“  μ…€μ˜ ν‘œμ‹œκΈ°λ₯Ό 초기 μ„€μ •ν•˜λŠ” 것은 μ–΄λ ΅μŠ΅λ‹ˆλ‹€. μ…€μ˜ 크기가 λ‹€λ₯΄κΈ° λ•Œλ¬Έμ—, 셀을 μŠ€μΊ”ν•˜λŠ” 것은 λ¬Έμ œκ°€ λ©λ‹ˆλ‹€. ν•˜λ‚˜μ˜ 해결책은 각 μ…€μ˜ 크기λ₯Ό 첫 번째 ν•„λ“œλ‘œ 갖도둝 μš”κ΅¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ³ μ •λœ 크기의 셀에 λΉ„ν•΄ μ•½κ°„ 더 λ§Žμ€ 곡간과 λ‹€μ†Œ λ§Žμ€ μ‹œκ°„μ΄ κ±Έλ¦¬μ§€λ§Œ μŠ€μΊ”μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

β€’ λ§ˆν‚Ή 과정은 μ‚¬μ†Œν•œ 것이 μ•„λ‹™λ‹ˆλ‹€. 포인터가 λ“€μ–΄κ°€λŠ” 셀에 ν¬μΈν„°μ˜ μœ„μΉ˜κ°€ 미리 μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šμ€λ° μ–΄λ–»κ²Œ ν¬μΈν„°μ—μ„œ λ”°λΌμ˜¬ 수 μžˆμ„κΉŒμš”? 포인터가 μ „ν˜€ μ—†λŠ” 셀도 λ¬Έμ œμž…λ‹ˆλ‹€. λŸ°νƒ€μž„ μ‹œμŠ€ν…œμ— μ˜ν•΄ λ°±κ·ΈλΌμš΄λ“œλ‘œ μœ μ§€λ˜λŠ” 각 셀에 λ‚΄λΆ€ 포인터λ₯Ό μΆ”κ°€ν•˜λ©΄ λ©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄λŸ¬ν•œ λ°±κ·ΈλΌμš΄λ“œ μœ μ§€ 관리 μ²˜λ¦¬λŠ” ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ λΉ„μš©μ— 곡간 및 μ‹€ν–‰ μ‹œκ°„ μ˜€λ²„ν—€λ“œλ₯Ό λͺ¨λ‘ μΆ”κ°€ν•©λ‹ˆλ‹€.

β€’ μ‚¬μš© κ°€λŠ₯ν•œ κ³΅κ°„μ˜ λͺ©λ‘μ„ μœ μ§€ν•˜λŠ” 것도 μ˜€λ²„ν—€λ“œμ˜ 또 λ‹€λ₯Έ μ›μ²œμž…λ‹ˆλ‹€. λͺ©λ‘μ€ μ‚¬μš© κ°€λŠ₯ν•œ λͺ¨λ“  κ³΅κ°„μœΌλ‘œ κ΅¬μ„±λœ 단일 μ…€λ‘œ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ„Έκ·Έλ¨ΌνŠΈμ— λŒ€ν•œ μš”μ²­μ€ λ‹¨μˆœνžˆ 이 λΈ”λ‘μ˜ 크기λ₯Ό μ€„μž…λ‹ˆλ‹€. 회수된 셀은 λͺ©λ‘μ— μΆ”κ°€λ©λ‹ˆλ‹€. λ¬Έμ œλŠ” μ˜€λž˜μ§€ μ•Šμ•„ λͺ©λ‘μ΄ λ‹€μ–‘ν•œ 크기의 μ„Έκ·Έλ¨ΌνŠΈ, 즉 λΈ”λ‘μ˜ κΈ΄ λͺ©λ‘μ΄ λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μš”μ²­μ΄ μΆ©λΆ„νžˆ 큰 블둝에 λŒ€ν•΄ λͺ©λ‘μ΄ κ²€μƒ‰λ˜κ²Œ ν•˜κΈ° λ•Œλ¬Έμ— 이것은 할당을 느리게 ν•©λ‹ˆλ‹€. κ²°κ΅­ λͺ©λ‘μ€ λŒ€λΆ€λΆ„μ˜ μš”μ²­μ— μΆ©λΆ„νžˆ 크지 μ•Šμ€ 맀우 μž‘μ€ λΈ”λ‘μ˜ 수λ₯Ό 많이 ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 μ‹œμ μ—μ„œ μΈμ ‘ν•œ 블둝은 더 큰 λΈ”λ‘μœΌλ‘œ λΆ•κ΄΄λ˜μ–΄μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λͺ©λ‘μ—μ„œ μΆ©λΆ„νžˆ 큰 첫 번째 블둝을 μ‚¬μš©ν•˜λŠ” λŒ€μ•ˆμ€ 검색을 λ‹¨μΆ•μ‹œν‚¬ 수 μžˆμ§€λ§Œ λͺ©λ‘μ„ 블둝 ν¬κΈ°λ³„λ‘œ μˆœμ„œν™”ν•  것을 μš”κ΅¬ν•©λ‹ˆλ‹€. 두 경우 λͺ¨λ‘ λͺ©λ‘μ„ μœ μ§€ν•˜λŠ” 것은 좔가적인 μ˜€λ²„ν—€λ“œμž…λ‹ˆλ‹€.

μ°Έμ‘° μΉ΄μš΄ν„°λ₯Ό μ‚¬μš©ν•˜λ©΄ 처음 두 가지 λ¬Έμ œλŠ” λ°©μ§€λ˜μ§€λ§Œ κ°€μš© 곡간 λͺ©λ‘ μœ μ§€ 관리 λ¬Έμ œλŠ” μ—¬μ „νžˆ 남아 μžˆμŠ΅λ‹ˆλ‹€. λ©”λͺ¨λ¦¬ 관리 λ¬Έμ œμ— λŒ€ν•œ 포괄적인 μ—°κ΅¬λŠ” Wilson(2005)을 μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

이 κΈ°μ‚¬λŠ” μ €μž‘κΆŒμžμ˜ CC BY 4.0 λΌμ΄μ„ΌμŠ€λ₯Ό λ”°λ¦…λ‹ˆλ‹€.