[회고록] Malloc Lab 프로젝트

emplam27·2021년 1월 24일
0

프로젝트

목록 보기
2/5

Malloc Lab 프로젝트 Github 링크

21.01.15 ~ 21.01.21

C언어를 이용하여 malloc함수를 구현하는 프로젝트였습니다. 동적할당에 대해 이해할 수 있는 시간이었고, 가상메모리의 주소에 직접 접근하여 할당하는 경험을 할 수 있는 기회가 되었습니다.


어려웠던 점

  1. 동적할당이 잘 수행되었는지 확인하는 heap checker를 구현하는 도중 설계단계에서 생각하지 못한 엣지케이스를 발견하였습니다. free한 블록들을 연결 리스트 형태로 구현하고 가장 처음 포인터만을 변수로 저장해 놨었는데, 엣지케이스 때문에 가장 마지막 블록에 접근해야 하는 일이 발생하였습니다. 문제점을 해결하기 위해 연결리스트를 head와 tail을 만드는 방법으로 수정하였습니다. 이후 더 설계를 수정하여 마지막에 들어오는 블록을 가장 처음에 연결하는 방법으로 성능을 개선하였습니다.

  2. 이중포인터를 사용하는데 어려움이 있었습니다. heap checker 구현 도중 implicit 방법에서 단일 포인터라고 선언해놓은 변수에 이중포인터를 할당해야하는 상황이 생겨버렸습니다. 할당 과정에서 여러 오류사항들이 생겨났고, 이중포인터를 사용하지 않는 방향으로 설계를 수정하였습니다.

  3. 포인터의 산술 연산에 대해서 공부하고, char형 포인터 산술연산과 이중포인터 산술연산을 같다고 생각했습니다. 또한 headtail 두개의 이중포인터 변수를 선언할 때 굉장히 다른 두 곳의 메모리 주소를 줄 것이라고 생각하고 있었습니다. 하지만 이중포인터의 산술연산, 변수의 선언 등 모두 의도와는 다른 작동 방식을 가지고 있었고, 결국 아래와 같이 두 변수의 값이 같아지는 상황이 발생하였습니다.

이중포인터의 산술연산 오류

char형 포인터의 산술연산은 1byte씩 이동하지만, char형 이중포인터의 연산은 8byte씩 이동합니다.

#include <stdio.h>

int main() {
    char c;
    char *char_ptr = &c;
    char **char_ptr_ptr = &char_ptr_ptr;

    printf("%p\n", char_ptr); 		// 000000000061FE17
    printf("%p\n", char_ptr + 1); 	// 000000000061FE18
    printf("%p\n", char_ptr_ptr); 	// 000000000061FE08
    printf("%p\n", char_ptr_ptr + 1); 	// 000000000061FE10
}   

두 포인터 변수의 선언 오류

두 포인터 변수는 선언 순서에 따라 유사한 메모리 공간에 할당되었고, 이중포인터 산술 연산에 의해 같은 값을 가지게 되었습니다.

#include <stdio.h>

void **head_ptr_ptr;
void **tail_ptr_ptr;
void *head_ptr;
void *tail_ptr;
int num = 1;

int main() {
    head_ptr = &num;
    head_ptr_ptr = &head_ptr - 1;
    tail_ptr = &num;
    tail_ptr_ptr = &tail_ptr;

    printf("head_ptr: %p\n", head_ptr); 	// 0000000000403010
    printf("tail_ptr: %p\n", tail_ptr); 	// 0000000000403010
    printf("&head_ptr: %p\n", &head_ptr); 	// 0000000000407988
    printf("&tail_ptr: %p\n", &tail_ptr); 	// 0000000000407980
    printf("head_ptr_ptr: %p\n", head_ptr_ptr); // 0000000000407980
    printf("tail_ptr_ptr: %p\n", tail_ptr_ptr); // 0000000000407980
}

배운점과 성과

  1. 설계 과정을 더 꼼꼼히 진행하며 엣지 케이스를 더 많이 고려해야함을 배울 수 있었습니다.

  2. 포인터와 이중포인터의 산술연산 차이, 변수 선언시 변수들이 어떻게 순서대로 메모리에 올라가는지 등 코드를 짜봐야 알수 있는 내용들을 알게 되었습니다. 메모리를 직접 건드리는 C언어 특성상 이런 부분들을 더 깊게 고려해야 한다는 것을 배웠습니다.

  3. 이전에 컴퓨터 구조에 대해 정리할 때, 저기 나온 내용들이 어떤 의미인지, 각 영역이 어떤 역할을 수행하는지 완전히 이해하지 못한체로 아래 그림을 그렸던 기억이 있습니다. 이번 프로젝트를 마치고 다시 이 그림을 봤을 때 드디어 이 그림이 이해가 갔습니다. 몰랐던 것을 알아가며 짧은 시간에 많은 성장을 하게 된 것 같아서 뿌듯합니다.


앞으로 해보고 싶은 공부

가상메모리, 페이지네이션 등 OS에 대한 더 깊은 공부를 진행해보고 싶습니다.

profile
내가 다시 보고 싶은 글이어야 남들도 보고 싶은 글이라 생각하며 작성합니다. 공부한 내용들을 건강하게 공유하며 함께 성장하고자 합니다😊😊

0개의 댓글