jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 3.9 이종 데이터 구조 (Heterogeneous Data Structures)
    1. 3.9.1 구조체 (Structures)
      1. 예시: 구조체 선언
      2. 요약
    2. 3.9.2 공용체 (Unions)
      1. 예시
      2. 메모리 절약
      3. 효과 예시
    3. 3.9.3 데이터 정렬(Data Alignment)
      1. Intel 정렬규칙
      2. 정렬 보장 방법

csapp 3장 오늘은 시마이 칠 생각이다


이 재미도 없는 걸 언제까지 붙들기는 싫으니 말이다


3.9 이종 데이터 구조 (Heterogeneous Data Structures)

C언어에서 타입끼리 결합해 데이터 타입을 만드는 2가지 방법이 있다

  • 구조체: struct 키워드를 사용해 여러 객체를 하나의 단위로 묶는다

  • 공용체: union키워드로 하나의 객체를 다른 여러 타입으로 참조가능케 한다


3.9.1 구조체 (Structures)

구현 방식은 배열과 유사하다고 한다

  • 모든 구성 요소는 연속적인 메모리 영역에 저장

  • 구조체 포인터는 구조체의 첫 번째 바이트 주소를 가리킴

  • 컴파일러는 각 구조체 타입에 대해 각 필드의 바이트 오프셋1 정보를 유지




예시: 구조체 선언

struct rec {
    int i;
    int j;
    int a[2];
    int *p;
};
  1. int i → 4바이트

  2. int j → 4바이트

  3. int a[2] → 8바이트 (int 2개)

  4. int *p → 8바이트 (포인터)

총 크기 = 24바이트

Offset 0 4 8 12 16
Field i j a[0] a[1] p

오프셋 값은 구조체 시작 주소로부터 각 필드의 떨어진 거리




필드 접근

컴파일러는 구조체 주소에 필드 오프셋 더해 구조체 필드에 접근한다

구조체 내부 객체의 포인터 생성

필드의 오프셋을 구조체 주소에 더하면 해당 필드의 주소를 얻을 수 있다


굳이 예시는 안들겠다

사실 당연한 내용이라



요약

  • 구조체의 필드 선택은 전적으로 컴파일 시점에 처리

  • 생성된 기계어 코드에는 필드 선언이나 이름 정보가 전혀 포함되지 않는다

  • 필드 접근은 구조체 시작 주소 + 오프셋 방식으로 처리



3.9.2 공용체 (Unions)

공용체(union)는 C언어 타입 시스템 우회란다
하나의 객체를 여러 타입으로 참조 가능케 말이다

선언 문법은 같지만 의미는 다르다

  • 구조체(struct)는 각 필드가 서로 다른 메모리 영역

  • 공용체(union)는 모든 필드가 같은 메모리 영역


예시

struct S3 {
    char c;
    int i[2];
    double v;
};

union U3 {
    char c;
    int i[2];
    double v;
};
타입 c i v 크기
S3 0 4 16 24
U3 0 0 0 8

각 필드의 오프셋과 전체 크기

S3에서 i 가 오프셋 4이고, v가 오프셋 16인 이유느 패딩 때문이다

  • p->c, p->i[0], p->v 모두 같은 시작 주소 참조

  • 공용체 전체 크기는 가장 큰 필드 크기


메모리 절약

공용체를 이용하면 메모리를 절약 가능하다

구조체는 모든 필드가 각자 메모리 공간을 가지기에 동시에 쓰지 않더라도 항상 공간 차지

공용체는 모든 필드가 같이 메모리 사용해서 한 시점에 하나의 필드만 사용

단, 필드들이 동시에 쓰이지 않는 경우여야 안전


구조체는 필드 크기 합계 + 패딩이 전체 크기

공용체는 가장 큰 필드의 크기가 전체 크기

따라서 크기 큰 필드를 공유하여 전체 크기 감소


효과 예시

  • 이진 트리 노드처럼 리프 노드내부 노드가 구조가 다른 경우

    • 구조체: 리프/내부 관계없이 모든 필드에 공간 할당 → 낭비 발생

    • 공용체: 리프용 데이터와 내부 노드용 포인터가 같은 공간을 공유 → 메모리 절반 수준으로 줄어듦



3.9.3 데이터 정렬(Data Alignment)

기본 데이터 타입이 저장될 수 있는 주소에 제한이 있다

어떤 객체의 주소가 특정값 K(일반적으로 2, 4, 8)의 배수가 되어야 한다는 규칙이다


x86-64에서의 경우를 예시로 보여준다

데이터 정렬 안 맞아도 작동은 하나 맞는게 성능에 좋아 권장한다 한다

Intel 정렬규칙

K 바이트 크기의 기본 객체 -> 주소는 K의 배수여야 함

K 값 타입
1 char
2 short
4 int, float
8 long, double, char *

정렬 보장 방법

  • 데이터 배치 시, 각 객체가 정렬 규칙 만족하도록 구성

  • 전역 데이터는 컴파일러가 .align 지시어로 강제 정렬

    • 예: .align 8 이후 데이터의 시작 주소가 8의 배수

구조체도 패딩2 등으로 규칙을 지킨다고 한다






  1. 첫 번째 필드의 주소를 기준으로 얼마나 떨어져 있는지 

  2. 아무의미 없는 바이트로 주소 맞추려고 쓴다