얼마 전에 겜회사 면접 봤는데 포인터 관련된 부분이 나와서 다시 공부할 겸 짜봄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #pragma once #include <memory> class memory_pool { public: memory_pool(size_t requested_size, size_t next_size = 32) : requested_size_(requested_size < min_size() ? min_size() : requested_size) , next_size_(next_size) , page_(nullptr) , first_(nullptr) { } ~memory_pool() { // 모든 페이지 해제 void* next; while (page_) { next = next_of(page_); std::free(page_); page_ = next; } } // 요청된 크기를 반환합니다. size_t requested_size() const { return requested_size_; } // 메모리를 할당합니다. void* malloc() { if (empty()) grow(); void* const ret = first_; first_ = next_of(first_); return ret; } // 메모리를 해제합니다. void free(void* chunk) { next_of(chunk) = first_; first_ = chunk; } // 여분 메모리가 존재하지 않는지 검사합니다. // true를 반환하는 상황에서 할당을 시도하면 메모리 풀의 성장이 일어납니다. bool empty() const { return first_ == nullptr; } // 풀을 확장합니다. void grow() { const size_t page_size = (requested_size_ * next_size_) + sizeof(void*); char* new_page = (char*)std::malloc(page_size); next_of(new_page) = page_; page_ = new_page; char* const end_of_page = new_page + page_size; new_page += sizeof(void*); while (new_page != end_of_page) { next_of(new_page) = first_; first_ = new_page; new_page += requested_size_; } next_size_ *= 2; } private: // 할당한 청크 그 자체를 다음 노드의 포인터를 저장할 공간으로 사용합니다. // chunk: [ ] => [nextptr] static void*& next_of(void* const chunk) { return *static_cast<void**>(chunk); } // 블록의 최소 사이즈를 반환합니다. static constexpr size_t min_size() { return sizeof(void*); } void* page_; void* first_; size_t next_size_; const size_t requested_size_; }; | cs |
댓글 0