Notice
Recent Posts
Recent Comments
Link
- 책_곽용재님 홈페이지
- 책_노란북 - 책 가격비교
- 책_김재우-SICP번역
- 플밍_쏘쓰포지
- 플밍_CodingHorror ?
- 플밍_상킴
- 플밍_김민장님
- GPGStudy
- 플밍_미친감자님
- 플밍_jz
- 플밍_샤방샤방님
- 플밍_글쓰는프로그래머2
- 플밍_키보드후킹
- 사람_재혁
- 사람_kernel0
- 사람_박PD
- 사람_경석형
- 사람_nemo
- 사람_kikiwaka
- 사람_Junios
- 사람_harry
- 사람_어떤 개발자의 금서목록..
- 사람_모기소리
- 사람_낙타한마리
- 사람_redkuma
- 사람_영원의끝
- 사람_민식형
- 도스박스 다음카페
- 플레이웨어즈 - 게임하드웨어벤치마크
- http://puwazaza.com/
- David harvey의 Reading Marx's c…
- 씨네21
- 한겨레_임경선의 이기적인 상담실
- 본격2차대전만화 - 굽시니스트
- 영화_정성일 글모음 페이지
- 영화_영화속이데올로기파악하기
- 음식_생선회
- 죽력고
- 사람_한밀
- 플밍_수까락
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- modernc++
- 단상
- 노무현
- 고등학교 사회공부
- 진중권
- c++
- 유머
- 인문학
- 태그가 아깝다
- 소비자고발
- 김두식
- template
- 책
- 삼국지
- 프로그래밍
- 영화
- 정성일
- programming challenges
- BSP
- stl
- 삼국지6
- 정신분석
- 진삼국무쌍5
- 일리아스
- 고전강의
- 건강
- 유시민
- 게임
- Programming
- 강유원
Archives
- Today
- Total
11-21 18:21
lancelot.com
allocator - policy base design 본문
- allocator
- 메모리 할당관련 함수를 추상화한 도구
- 메모리 할당 방식을 쉽게 변경할 수 있게 해준다.
- std::allocator
- C++ 표준 메모리 할당기
- 기본 구현은 operator new() / operator delete() 사용
- allocator 멤버함수 - 사용자 정의 allocator를 만들기위해서는 아래 멤버함수 구현 필요
- allocate : 메모리 할당
- construct : 생성자 호출
- destroy : 소멸자 호출
- deallocate 메모리 해제
- 사용자정의 allocator를 STL에 전달하려면
- default constructor
- template constructor
- value_type member
- == 연산, != 연산 이 가능해야한다
#include<iostream>
#include"point.h"
template<typename T>
class MyAlloc
{
public :
T* allocate(std::size_t n)
{
T* p = static_cast<T*>(std::malloc(n * sizeof(T)));
std::cout << "allocate" << std::endl;
return p;
}
void deallocate(T* p, std::size_t n) noexcept
{
free(p);
std::cout << "deallocate" << std::endl;
}
template<typename ... ARGS>
void construct(T* p, ARGS&& ... args)
{
new(p) T(std::forward<ARGS>(args)...);
std::cout << "MyAlloc constructor" << std::endl;
}
void destroy(T* p)
{
p->~T();
std::cout << "MyAlloc destroy" << std::endl;
}
};
int main()
{
// 아래처럼 new/delete 를 사용하는 코드가 10곳에 있는데,
// 메모리 할당해지 방식을 변경하고 싶다면?
// -> 10곳 모두 수정해야한다.
Point* p1 = new Point(1, 2);
delete p1;
// 대신 allocator 라는 메모리할당자를 사용한다
// std::allocator<Point> ax;
MyAlloc<Point> ax;
// 와 같이 해서 allocator를 쉽게 변경할 수 있다.
Point* p2 = ax.allocate(1);
ax.construct(p2, 0, 0);
ax.destroy(p2);
ax.deallocate(p2, 1);
}
- std::allocator_traits ( C++11 )
- construct, destroy 등 allocator 관련 함수의 기본 구현을 제공
- 사용자 정의 allocator 안에 construct / destroy 함수가
- 있는 경우 : 사용자가 만든 construct 함수 사용
- 없는 경우 : allocator_traits 가 디폴트 구현 제공
- std::allocator
- C++20 이전 : allocator / deallocator / construct / destroy 모두 제공
- C++20 부터 : construct / destroy 함수 제공 안함
template<typename T>
class MyAlloc
{
...
using value_type=T; // allocator_traits<> 를 사용하려면 필요
}
int main()
{
Point* p1 = ax.allocate(1);
ax.construct(p1, 0, 0);
ax.destroy(p1);
ax.deallocate(p1, 1);
// allocator::traits<> 사용
Point* p2 = std::allocator_traits < MyAlloc<Point>>::allocate(ax, 1);
std::allocator_traits<MyAlloc<Point>>::construct(ax, p2, 0, 0);
std::allocator_traits<MyAlloc<Point>>::destroy(ax, p2);
std::allocator_traits<MyAlloc<Point>>::deallocate(ax, p2, 1);
}
- MyAlloc 을 제작한 Vector에 적용
#include<iostream>
#include"point.h"
#include"MyAlloc.h"
template<typename T, typename Alloc=std::allocator<T> >
class Vector
{
T* buff;
std::size_t size;
std::size_t capacity;
Alloc ax;
public :
Vector(std::size_t sz, const T& value) : size(sz), capacity(sz)
{
// memroy allocation
// buff = new T[sz];
// buff = static_cast<T*>(operator new(sizeof(T)*sz));
buff = std::allocator_traits<Alloc>::allocate( ax, sizeof(T)*sz );
// construction
int i = 0;
try
{
for (i = 0; i < sz; ++i)
{
// new(&buff[i]) T; // default constructor
// new(&buff[i]) T(value); // copy constructor
std::allocator_traits<Alloc>::construct(ax, &buff[i], value);
}
}
catch (...)
{
for (int j = i - 1; j >= 0; --j)
// buff[j].~T();
std::allocator_traits<Alloc>::destroy(ax, &buff[i]);
// operator delete(buff);
std::allocator_traits<Alloc>::deallocate(ax, buff, capacity);
size = 0;
capacity = 0;
throw;
}
}
~Vector()
{
// delete[] buff;
for (__int64 j = size - 1; j >= 0; --j)
// buff[j].~T();
std::allocator_traits<Alloc>::destroy(ax, &buff[j]);
// operator delete(buff);
std::allocator_traits<Alloc>::deallocate(ax, buff, capacity);
}
};
int main()
{
Point pt(0, 0);
Vector<Point> v(10, pt);
Vector<Point, MyAlloc<Point>> v2(10, pt);
return 0;
}
- STL 에 전달을 위한 4가지 조건이 적용된 최종 MyAlloc
template<typename T>
struct MyAlloc
{
T* allocate(std::size_t n)
{
T* p = static_cast<T*>(std::malloc(n * sizeof(T)));
std::cout << "allocate" << std::endl;
return p;
}
void deallocate(T* p, std::size_t n) noexcept
{
free(p);
std::cout << "deallocate" << std::endl;
}
template<typename ... ARGS>
void construct(T* p, ARGS&& ... args)
{
new(p) T(std::forward<ARGS>(args)...);
std::cout << "MyAlloc constructor" << std::endl;
}
void destroy(T* p)
{
p->~T();
std::cout << "MyAlloc destroy" << std::endl;
}
using value_type = T;
// template constructor
template<typename U>
MyAlloc(const MyAlloc<U>&) noexcept {}
// template constructor 가 있으니 default constructor 가 자동생성이 안되므로 만들어준다
MyAlloc() = default;
};
// ==
template<typename T, typename U>
bool operator==(const MyAlloc<T>&, const MyAlloc<U>&) { return true; }
// !=
template<typename T, typename U>
bool operator!=(const MyAlloc<T>&, const MyAlloc<U>&) { return false; }