
64비트 환경에서 Malloc Lab을 구현하려고 시도했었다.
64비트 환경으로 변경하려 했던 이유로는 두 가지가 있다.

그런데 Malloc Lab은 기본 설정이 32비트 환경이다.
또한 CSAPP 교재에서의 코드도 32비트를 기준으로 한다.
오탈자일까?
결국 오류들을 해결하지 못해 포기했지만, 시도 과정에서 32비트와 64비트 환경의 차이들을 뚜렷하게 느낄 수 있었다.
구현하면서 느낀 차이점들을 정리해보았다.
가장 처음 마주한 문제는 pred, succ 같은 포인터 저장이었다.
32비트에서 포인터의 크기는 4바이트지만, 64비트에서는 8바이트이다.
이로 인해 따라서 포인터 전용 매크로를 새로 만들어야 했다.
기존 GET / PUT 매크로는 4바이트 기준으로 작성되어 있기 때문이다.
#define GET(p) (*(unsigned int *)(p))
#define PUT(p, val) (*(unsigned int *)(p) = (val))
이 매크로를 64비트 주소에 사용하면 주소가 절반만 저장되어 오류가 발생한다.
#define GET_PTR(p) (*(void **)(p))
#define PUT_PTR(p, val) (*(void **)(p) = (val))
따라서 포인터 전용 매크로를 따로 만들어주었다.
64비트 환경에서는 포인터나 size_t가 8바이트이므로 정렬 단위도 8바이트다.
또한, double word는 16바이트 단위로 사용된다.
이에 따라 블록 크기도 커지고, 매크로도 변경이 필요했다.
#define WSIZE 8
#define DSIZE 16
#define ALIGNMENT 8
#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~0x7)
정렬을 제대로 하지 않으면 payload가 8바이트 정렬되지 않아 segfault가 발생할 수 있다.
기존 매크로는 unsigned int 기반이었으나, 64비트 환경에선 부족하다.
size_t를 기반으로 바꿔야 한다:
#define GET(p) (*(size_t *)(p))
#define PUT(p, val) (*(size_t *)(p) = (val))
또한, HDRP, FTRP, NEXT_BLKP, PREV_BLKP 등의 포인터 연산도 8바이트 정렬 기준으로 수정해야 한다.
컴파일 시 오류 방지를 위해 -m64 옵션을 명시적으로 넣는 것이 안전하다.
CFLAGS = -Wall -Werror -m64
또한 memlib.c 내에서 mem_sbrk() 등의 포인터 연산도 64비트에 맞게 size_t 또는 void * 기반으로 고쳐야 했다.
나는 결국 도무지 오류를 해결할 수 없어서 64비트 구현을 포기하고 32비트로 시도했다.
하지만 이 과정을 통해 32비트와 64비트의 차이점에 대해 확실히 배울 수 있었다.
추가로 C는 메모리 단위에서 정말 세심한 관리가 필요하구나,를 절실히 느낀 실패였다.
C는 세심한 관리가 필요한 친구였네요~~
화이팅입니다 ^^b