typedef struct LIST_ENTRY_TAG {
struct LIST_ENTRY_TAG *next;
struct LIST_ENTRY_TAG *prev;
int data;
} LIST_ENTRY;
LIST_ENTRY head;
...
LIST_ENTRY *add_list_entry(LIST_ENTRY *head, int data) {
LIST_ENTRY *new_entry = new LIST_ENTRY;
new_entry->next = head;
new_entry->prev = head->prev;
new_entry->prev->next = new_entry;
head->prev = new_entry;
return new_entry;
}
void delete_list_entry(LIST_ENTRY *entry) {
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
delete entry;
}
add 함수에서 data를 구조체에 복사하지 않은 건 나의 실수~
근데 급하게 짜서 올려서 구조체는 C 스타일로 만들어 놓고 함수 코드에서는 new/delete를 쓰고 있네 ㅡ.ㅡ;
head 전역인것 같은데 다시 인자로?
리스트를 여러 개 만들어서 쓰라는 배려인 거죠. 후훗
글구 헤드 포인터로 선언할 의도 아니셨음? ^^
헤드에 존재하는 dummy entry 항목이에요.
거추장스럽게 LIST_ENTRY *head, *tail; 로 선언하고 쓰는 것보단 저게 깔끔하죠.
웅 하나 깔고 시작했구낭.
저게 코드도 깔끔해져서 많이들 저렇게 하더라고요. 윈도우 커널에서도 프로세스 목록 관리할 때 EPROCESS 구조체 간의 연결 리스트가 저런 구조로 되어 있어요. 작업 관리자 프로세스 탭에 보이는 System Idle Process 프로세스가 그 역할이죠.
코드로 접근한다면 PsInitialSystemProcess->ActiveProcessLinks.Blink
포인터만 가리키고 정작 데이터는 잡아먹어부렸엉?
난 전역시점 초기화는 잘 안쓰게되더라. 할당 해제 시점을 분명히 해야하는 경우가 많아성 : )
중딩3 // 사실 저렇게 짜는 것보단 포인터만 가지고 있는 Linked List용 구조체 타입을 하나 정의하고 그걸 자료 구조체 안에 넣어서 쓰는 게 더 깔끔하긴 함. 이 글 코드는 내가 급하게 급조해낸 코드여서 실수도 많고 좀 허접하네~
필요한 부분은 다 표현되어 있으니 충분하지. 아가들 설명용인데. : )
윈도우 커널만 보더라도 LIST_ENTRY라는 구조체를 따로 정의해 놓고 다른 구조체 내부 멤버로 LIST_ENTRY를 가짐으로써 연결 리스트를 구현하고 있음. 윈도우 커널의 CONTAINING_RECORD() 매크로나 리눅스 커널의 container_of() 매크로는 Linked List Structure 포인터에서 자료 구조체 포인터를 구하기 위해 만들어진 매크로들이지.
어릴땐 메모리 좀 손해보더라도 worst cast 를 줄여야징 하고 double linked list 자주 썼는뎅 막상 실무에서 쓰는 경우는 거의 없더라. 스타일이지만 ^ㅡ^
ㄷㄷㄷ
head 라고 받아서 next 가 되니 헷갈릴듯.
모르는데 깝치지 않겠읍니다