Re: Linked list에 관한 문제점과 보안점을 생각해봤습니다.
, 도장_ 관리자님이 작성해당 과정은 고려하지 않아도 됩니다.
리스트 해제 도중 중단되는 상황은 프로그램이 중단된 것에 해당합니다.
즉, program crashed -> aborted 상태이면 프로그램은 종료된 것이고,
해제되지 못했던 메모리를 포함해서 프로그램이 사용한 모든 메모리에는 운영체제에 의해 반환됩니다.
문의한 사항은 프로그래밍에서 고려 대상이 되지 않습니다.
가장 널리 쓰이는 현대 운영체제 중에 하나인 리눅스 커널도 간단히 리스트를 제거할 뿐입니다.
https://github.com/torvalds/linux/blob/master/include/linux/list.h
static inline void __list_del(struct list_head * prev, struct list_head * next) |
{ |
next->prev = prev; |
WRITE_ONCE(prev->next, next); |
리눅스 커널이 리스트를 해제하는 과정 중에 중단되었다면 커널 실행에 문제가 발생한 것이니 운영체제가 중단되고, 시스템은 먹통이 되는 상황이니 재부팅을 하면 됩니다.
head->next = next;를 추가해서 이익을 얻을 수 있으려면 해제하는 과정에서 프로그램이 중단되는 상황이 발생했을 때 그 중단을 막고 리커버리할 수 있어야 하는데, 시스템 프로그램에서 그런 상황은 대체로 없습니다. 해제 과정에서 프로그램이 죽었는데 head->next = next;가 어떤 의미가 있을까요?
버그 없이 제대로 동작하는 프로그램을 작성하는 게 더 낫습니다.
static inline void list_splice_tail(struct list_head *list, |
struct list_head *head) |
{ |
if (!list_empty(list)) |
__list_splice(list, head->prev, head); |
비어 있는 리스트에 작업하면 안 되는 경우에 !list_empty(list)처럼 리스트가 비어 있지 않은지 확인하는 sanity check를 하는 올바른 코드를 작성하는 것이 더 중요합니다.
책의 예제는 개념을 설명하기 위해 간략화된 것이고, 실무에 쓰이는 수준의 자료 구조 구현을 알고 싶다면 리눅스 커널의 연결 리스트나 잘 알려진 오픈 소스의 연결 리스트 구현을 살펴보는 게 좋습니다. 책에서 소개하는 자료 구조는 어떤 책, 어떤 예제라도 학습을 위해 간략화되어 있고, 실무에 쓰이는 지저분한 방법보단 이상적인 깔끔한 방법만을 제시하는 경향이 있다는 점도 참고하세요.
리눅스 커널뿐 아니라 대다수 C 언어 프로젝트는 공통 자료 구조에 대해 헤더 파일 .h에 매크로와 인라인 함수로 구현합니다. 자료구조 책은 이를 따르지 않는데, 이는 학습과 실무 사이에 큰 벽이 있기 때문입니다. 이걸 설명하면 따라올 학생도 거의 없고, 학생 스스로 많은 시간을 들여 학습해야 하지만, 학교나 학원 같은 교육 현장에서는 리눅스 커널의 연결 리스트 구현 방식을 처음 보는 경우도 많습니다.
배열이나 트리 구조도 judy array나 judy tree 같은 오픈 소스를 분석하면 실무 수준의 스킬을 얻는 데 도움이 되지만, 학생 수준에서는 거의 필요 없습니다. 입사한 회사와 팀에서 쓰는 자료구조와 오픈 소스가 따로 있고, 그걸 학습해서 쓰게 됩니다.
깊이 학습하는 것보단 폭넓게 다양한 것들을 학습하며 기초만 쌓으세요. 어딜 가도 살아 남을 수 있는 생존력에 보탬이 될 수 있는...